<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wiki-Mikee63</id>
	<title>OSGeo - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.osgeo.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wiki-Mikee63"/>
	<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/wiki/Special:Contributions/Wiki-Mikee63"/>
	<updated>2026-04-12T09:42:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=User:Mikee63&amp;diff=38983</id>
		<title>User:Mikee63</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=User:Mikee63&amp;diff=38983"/>
		<updated>2009-06-03T09:18:04Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;[[Image:Example.jpg]]&amp;lt;td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;CODE&amp;gt;&lt;br /&gt;
  Mike Elstermann&amp;lt;br&amp;gt;&lt;br /&gt;
  Teamleiter Softwareentwicklung&amp;lt;br&amp;gt;&lt;br /&gt;
  Kompetenzzentrum Geo-Systeme&amp;lt;br&amp;gt;&lt;br /&gt;
  IT-Consult Halle GmbH&amp;lt;br&amp;gt;&lt;br /&gt;
  Bornknechtstraße 5&amp;lt;br&amp;gt;&lt;br /&gt;
  06108 Halle (Saale)&amp;lt;br&amp;gt;&lt;br /&gt;
  Telefon: +49 345 581 7128&amp;lt;br&amp;gt;&lt;br /&gt;
  Telefax: +49 345 581 1737&amp;lt;br&amp;gt;&lt;br /&gt;
  PC-Fax: +49 345 581 78 7128&amp;lt;br&amp;gt;&lt;br /&gt;
  E-Mail: mike.elstermann@itc-halle.de&amp;lt;br&amp;gt;&lt;br /&gt;
  http://www.mikee.de&amp;lt;br&amp;gt;&lt;br /&gt;
  http://halgis.halle.de&amp;lt;br&amp;gt;&lt;br /&gt;
  http://umweltatlas.halle.de&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/CODE&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=37378</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=37378"/>
		<updated>2009-04-03T08:10:11Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* TrueType-Symbole */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= [[HBUMNMapServer_ger_Capter_1 | Einführung]] =&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
==Bedeutung des Mapfiles==&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
===MapServer als CGI===&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
===Die Modi===&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die weiteren Parameter===&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
==Grundlegender Aufbau des Mapfiles==&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
==Der Header==&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
==Die Web-Sektion==&lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
==Layer==&lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
===Gruppierungen von Layern===&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Weitere Layer-Optionen===&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=== Diagramme ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Classes==&lt;br /&gt;
\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=== Gruppierungen von Classes ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Styles==&lt;br /&gt;
(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten==&lt;br /&gt;
(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
===Bildkataloge===&lt;br /&gt;
(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
===Rasterdaten klassifizieren===&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
===Umprojizieren von Rasterdaten===&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
===Rasterdaten mit GDAL===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektordaten==&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
===Indizes für Shapefiles===&lt;br /&gt;
\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
===GRID-Layer===&lt;br /&gt;
\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
==Projektionen==&lt;br /&gt;
(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
===Notation===&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
===Orthographische Projektion===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
===Projektionen im realen Einsatz===&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
==Schriften==&lt;br /&gt;
\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
==Annotationen==&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
===Die Label-Sektion===&lt;br /&gt;
\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
===Bitmap-Schriften===&lt;br /&gt;
\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
===TrueType-Schriften===&lt;br /&gt;
\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
=== Beschriftungen ohne Annotationslayer ===&lt;br /&gt;
&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Der Label-Cache ===&lt;br /&gt;
&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
===Hinweise===&lt;br /&gt;
(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Symbole==&lt;br /&gt;
\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
===TrueType-Symbole===&lt;br /&gt;
\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen in [pix]. Kommt nur für Linien zur Anwendung. ''(Hinweis: GAP 30 erzwingt einen Abstand von 30 Pixeln, dreht aber alle TTF-Symbole auf 0 Grad, GAP -30 erzwingt ebenfalls einen Abstand von 30 Pixeln, richtet aber die Symbole an der Linie aus!)''  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
===Pixmap-Symbole===&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Overlay-Symbole===&lt;br /&gt;
\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
===Beispiele===&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
==Maßstäbe==&lt;br /&gt;
(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==Legenden==&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
===Die klassische MapServer-Legende===&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
===HTML-Legenden===&lt;br /&gt;
\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=== GetLegendGraphics Request ===&lt;br /&gt;
&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Templates==&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
===Die verschiedenen Arten von Templates===&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
===Aufbau===&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Metadaten==&lt;br /&gt;
(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Queries==&lt;br /&gt;
\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
===Notation 2===&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
   FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   CLASS&lt;br /&gt;
     TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 gemeinden_header.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
===Query maps===&lt;br /&gt;
\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 QUERYMAP&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
   SIZE 200 200&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   STYLE HILITE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
    queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
    [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Weitere Arten von Queries===&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;indexquery&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
;itemquery und itemnquery&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
   FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   FILTER &amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
;featurequery und featurenquery&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
;itemfeaturequery und itemfeaturenquery&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==PostgreSQL und PostGIS==&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
==OGR==&lt;br /&gt;
\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Spezifikation von Ausgabeformaten==&lt;br /&gt;
(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;png&amp;quot;&lt;br /&gt;
   DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
   IMAGEMODE RGB&lt;br /&gt;
   EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
===Rasterbilder===&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
   DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
   IMAGEMODE RGB&lt;br /&gt;
   EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
   FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
;Der GD-Treiber&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
;Der GDAL-Treiber&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
===Vektorformate===&lt;br /&gt;
(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
==Features==&lt;br /&gt;
(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 FEATURE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     10 10&lt;br /&gt;
     10 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
===Fix positionierte Elemente===&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
   STATUS DEFAULT&lt;br /&gt;
   TRANSFORM FALSE&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   FEATURE&lt;br /&gt;
     POINTS&lt;br /&gt;
       10 10&lt;br /&gt;
     END&lt;br /&gt;
     TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
       SIZE 11&lt;br /&gt;
       ANTIALIAS TRUE&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END									 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
==CGI-Parameter==&lt;br /&gt;
(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
===Parameter einschränken===&lt;br /&gt;
(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
    &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=== Variablensubstituion ===&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Logging==&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
==Includes==&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
==Joins==&lt;br /&gt;
\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 nicht mehr verwendet&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
;PDF&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
   DRIVER PDF&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
;Shockwave Flash&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
   DRIVER swf&lt;br /&gt;
   IMAGEMODE PC256&lt;br /&gt;
   FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
   # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
;Logs&lt;br /&gt;
(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_7&amp;diff=34436</id>
		<title>HBUMNMapServer ger Capter 7</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_7&amp;diff=34436"/>
		<updated>2009-01-23T10:22:11Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Werkzeuge der GDAL-Bibliothek */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Zusätzliche Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Viele kleine Werkzeuge stehen bereit, die das Drumherum um eine (potenzielle) MapServer-Anwendung anreichern. Und einige sind sogar ziemlich nützlich. Im folgenden sollen die Kommandozeilenwerkzeuge besprochen werden, die in den Quellcodepaketen der Shapelib, des MapServers und der Bibliothek GDAL bzw. OGR zu finden sind.&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge der Bibliothek Shapelib=\index{Shapelib}&lt;br /&gt;
&lt;br /&gt;
Diese Bibliothek wird auch vom MapServer verwendet, nämlich um -- wenig überraschend -- mit Shapefiles umzugehen. Allerdings wird dabei keine im System installierte Shapelib benutzt. Der MapServer bringt die entsprechenden Dateien in seinem eigenen Quellcodepaket mit.&lt;br /&gt;
&lt;br /&gt;
Das gilt jedoch leider nicht für die ganzen Werkzeuge der Shapelib. Möchte man also die Vorteile dieser kleinen Tools genießen, muß man es auf sich nehmen und die Shapelib extra kompilieren und installieren. Das ist schnell und einfach getan, indem man das Paket auspackt, in das neu entstandene Verzeichnis wechselt und mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # make&lt;br /&gt;
 # cd contrib&lt;br /&gt;
 # make&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
das Ganze hinter sich bringt.&lt;br /&gt;
&lt;br /&gt;
Man hat dann sowohl im Hauptverzeichnis des Quelltextes als auch im Unterverzeichnis =contrib=  jeweils einige kleine Programme, die man sich an entsprechende Stellen im System kopieren muß. Das Verzeichnis =/usr/local/bin=  kommt auf Unix-Systemen gerne zum Einsatz.&lt;br /&gt;
&lt;br /&gt;
==shpdump==\index{shpdump}&lt;br /&gt;
&lt;br /&gt;
Das Programm =shpdump=  gibt den Inhalt eines Shapefiles in Textform auf der Kommandozeile aus. Das sieht für das Shapefile =lakespy2.shp=  aus dem offiziellen Itasca-Demo beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpdump lakespy2.shp&lt;br /&gt;
&lt;br /&gt;
 Shapefile Type: Polygon   # of Shapes: 1379&lt;br /&gt;
&lt;br /&gt;
 File Bounds: (  393234.394, 5208170.531,0,0)&lt;br /&gt;
          to  (  495403.171, 5303964.877,0,0)&lt;br /&gt;
&lt;br /&gt;
 Shape:0 (Polygon)  nVertices=38, nParts=1&lt;br /&gt;
   Bounds:(  404885.933, 5292677.993, 0, 0)&lt;br /&gt;
       to (  405418.198, 5293262.006, 0, 0)&lt;br /&gt;
      (  405040.809, 5292726.997, 0, 0) Ring &lt;br /&gt;
      (  404949.931, 5292756.498, 0, 0)  &lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besonders schön ist die Angabe der Bounding Box ganz zu Beginn, da man auf diese Weise schnell die Extents eines Shapefiles in Erfahrung bringen kann.&lt;br /&gt;
&lt;br /&gt;
==shpcreate, shpadd, dbfcreate und dbfadd==\index{shpcreate}\index{shpadd}\index{dbfcreate}\index{dbfadd}&lt;br /&gt;
&lt;br /&gt;
Was diese Programme tun, kann man bereits aus ihrem Namen ersehen, und der geneigte Leser mag sich fragen, wer auf die Idee kommt, auf der Kommandozeile von Hand Shapefiles zu erstellen bzw. diesen Shapfiles von Hand Shapes hinzuzufügen?&lt;br /&gt;
&lt;br /&gt;
Diese Frage fußt auf einem Mißverständnis, dem viele Menschen erliegen, die es nicht gewohnt sind, auf der Kommandozeile zu arbeiten. Tatsächlich benutzt man dieses Programm eher selten von Hand. Viel häufiger werden solche Werkzeuge als Kommandos in Skripten eingesetzt, wo sie ihre ganze Macht entfalten können.&lt;br /&gt;
&lt;br /&gt;
Das Programm =shpcreate=  erstellt eine neue Shapedatei, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpcreate bla.shp polygon&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise wird ein leeres Polygon-Shapefile kreiert. Beachten Sie, dass das noch nicht die dazugehörige ''.dbf'' -Datei beinhaltet! Mögliche Shapefiletypen sind =point= , =arc= , =polygon=  und =multipoint= .&lt;br /&gt;
&lt;br /&gt;
Das hinzufügen von Punkten zu diesem neuen Shapefile ist ganz einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpadd bla.shp 1000 2000 2000 3000 3000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird dem Shapefile ein einzelnes Shape mit drei Punkten hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Natürlich möchte man seinem Shapefile auch eine ''.dbf'' -Datei an die Seite stellen. Das kann mit =dbfcreate=  geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfcreate bla.dbf -s NAME 20 -n FLAECHE 10 5&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese ''.dbf'' -Datei erhält zwei Spalten; als erstes eine 20 Zeichen große String-Spalte, und danach eine Spalte für numerische Einträge mit 10 Stellen, von denen 5 Nachkommastellen sind. Mehr Optionen gibt es für dieses Programm auch nicht.&lt;br /&gt;
&lt;br /&gt;
Sodann sollen der Datei selbstverständlich auch Daten hinzufügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfadd bla.dbf Mesopotamien 20.4&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise Daten, die man aus anderen Datenquellen hat, bequem in einem Skript automatisch in ein Shapefile umwandeln.&lt;br /&gt;
&lt;br /&gt;
==dbfdump==\index{dbfdump}&lt;br /&gt;
&lt;br /&gt;
Diese kleine Tool macht für ''.dbf'' -Dateien überraschenderweise das, was =shpdump=  für Shapefiles tut. Eine kleine Beispielausgabe anhand der Datei =airports.dbf=  aus dem offiziellen Itasca-Demo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfdump -h airports.dbf&lt;br /&gt;
 Field 0: Type=String, Title=`NAME', Width=64, Decimals=0&lt;br /&gt;
 Field 1: Type=Double, Title=`LAT', Width=12, Decimals=4&lt;br /&gt;
 Field 2: Type=Double, Title=`LON', Width=12, Decimals=4&lt;br /&gt;
 Field 3: Type=Double, Title=`ELEVATION', Width=12, Decimals=4&lt;br /&gt;
 Field 4: Type=String, Title=`QUADNAME', Width=32, Decimals=0&lt;br /&gt;
 NAME                      LAT      LON       ELEVATION QUADNAME&lt;br /&gt;
 Bigfork Municipal Airport 47.7789  -93.6500  1343.0000 Effie&lt;br /&gt;
 Bolduc Seaplane Base      47.5975  -93.4106  1325.0000 Balsam Lake&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Parameter =-h=  weist das Programm an, zusätzlich noch die Header-Informationen für die Datei auszugeben.&lt;br /&gt;
&lt;br /&gt;
==shpinfo==\index{shpinfo}&lt;br /&gt;
&lt;br /&gt;
Dieses kleine Programm gibt einige grundlegende Informationen über ein Shapefile aus. Am Beispiel der Datei ''airports.shp''  aus dem offiziellen Itasca County-Demo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpinfo airports.shp&lt;br /&gt;
 Info for airports.shp&lt;br /&gt;
 Point(1), 12 Records in file&lt;br /&gt;
 File Bounds: (              0,              0)&lt;br /&gt;
 (         496393,        5291930)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir haben also ein Punkt-Shapefile mit 12 Shapes vor uns.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass dieses Programm als minX/minY-Koordinaten selten etwas anderes ausgibt als 0/0, und für minimale Koordinaten daher nicht wirklich geeignet ist.&lt;br /&gt;
&lt;br /&gt;
==dbfinfo==\index{dbfinfo}&lt;br /&gt;
&lt;br /&gt;
Was ''shpinfo''  für Shapedateien ist, ist dieses Werkzeug für die dazugehörigen ''.dbf'' -Datensätze. Eine Beispielausgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# dbfinfo airports.dbf&lt;br /&gt;
 Info for airports.dbf&lt;br /&gt;
 5 Columns,  12 Records in file&lt;br /&gt;
            NAME	         string  (64,0)&lt;br /&gt;
             LAT	          float  (12,4)&lt;br /&gt;
             LON	          float  (12,4)&lt;br /&gt;
       ELEVATION	          float  (12,4)&lt;br /&gt;
        QUADNAME	         string  (32,0)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge des MapServers=&lt;br /&gt;
&lt;br /&gt;
Nach dem Kompilieren des MapServers findet man im Quellverzeichnis das eine oder andere kleine Werkzeug. Zwei sollen uns im folgenden besonders interessieren.&lt;br /&gt;
&lt;br /&gt;
==shp2img==\index{shp2img}&lt;br /&gt;
&lt;br /&gt;
Dieses Programm ist im wesentlichen MapServer für die Kommandozeile. Der Aufruf sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shp2img -m mapfile.map -i PNG -e 13.0 44.5 33.3 59.6&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird das entsprechende Mapfile dazu benutzt, ein PNG-Bild mit den angegebenen Extents zu erzeugen. Die Kartendarstellung wird dabei aus =mapfile.amp=  bezogen.&lt;br /&gt;
&lt;br /&gt;
Sie können dieses Programm beispielsweise dann benutzen, wenn Sie keinen Zugriff auf einen im Webserver installierten MapServer haben können oder möchten. Es eignet vor allen Dingen zum Debuggen von Mapfiles auf Systemen ohne MapServer.&lt;br /&gt;
&lt;br /&gt;
Alle möglichen Kommandozeileparameter werden durch einen Aufruf von =shp2img=  ohne Optionen ausgegeben.&lt;br /&gt;
&lt;br /&gt;
==shptree==\index{shptree}(2)&lt;br /&gt;
&lt;br /&gt;
Wenn eine Karte gezeichnet werden soll, muß theoretisch jedes einzelne Shape in einem Shapefile darauf geprüft werden, ob es tatsächlich angezeigt werden soll. Das kann offensichtlich sehr zeitaufwendig sein.&lt;br /&gt;
&lt;br /&gt;
Das Werkzeug ''shptree''  schafft hier Abhilfe, indem es einen so genannten Quadtree-Index über den Inhalt des Shapfiles erzeugt. Die Idee ist, dass man das gesamte Shapfile in vier verschiedene Gebiete zerlegt, die ihrerseits wiederum zerlegt werden, und so weiter. Diese Art der Zerlegung wird in einer Indexdatei mit der Endung ''.qix''  gespeichert.&lt;br /&gt;
&lt;br /&gt;
Wenn nun eine Karte generiert werden soll, werden zuallererst Vergleiche mit dem Index angestellt, um herauszufinden, auf welche Shapes man sich bei der Darstellung überhaupt konzentrieren soll. Gerade bei großen Datenmengen kann sich die Geschwindigkeit des MapServers dabei signifikant erhöhen. Beachten Sie jedoch, dass sich dieser Index ausschließlich auf die Vektordaten im Shapfile bezieht und keine Geschwindigkeitsverbesserung für zum Beispiel Attributanfragen liefert.&lt;br /&gt;
&lt;br /&gt;
Das Programm wird normalerweise sehr simpel angewendet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shptree shapefile.shp&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt noch zwei weitere Optionen für das Programm, der genaue Aufruf wird definiert als&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 shptree [shapefile] &amp;lt;tiefe&amp;gt; &amp;lt;byteorder&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Tiefe ist die Tiefe des Baumes gemeint, der erzeugt werden soll. Davon hat diese Art von Index auch ihren Namen. Man kann sich die Unterteilung des Shapfiles auch als Verzweigung in verschiedene Äste vorstellen, die sich dann wieder verzweigen und so weiter.&lt;br /&gt;
&lt;br /&gt;
Die Byteorder ist eine kleine informatische Spezialität. Alle Daten werden als Bits gespeichert, und 8 solcher Bits werden zu einem Byte zusammengefaßt. 'Normale' ganzzahlige Werte sind auf Intel-Computern beispielsweise 4 Byte lang. Unterschiedlich ist aber nicht nur die Menge an Platz, die Zahlen einnehmen können, sondern auch wie sie abgespeichert werden. Ohne weiter ins Detail gehen zu wollen: es gibt verschiedene Ansätze, beispielsweise zuerst das niederwertigste Bit in einem Byte zu speichern und die anderen dahinter anzuordnen -- oder aber umgekehrt. Diese Ansätze unterscheiden sich von Plattform zu Plattform.&lt;br /&gt;
&lt;br /&gt;
Rufen Sie einmal das Programm ohne jeden Parameter auf, um eine Liste der möglichen Byteorders zu Gesicht zu bekommen. Generell kann man sagen, dass es am sinnvollsten ist, keine Byteorder anzugeben und das Programm shptree ganz einfach einmal für alle Daten auf dem Zielsystem aufzurufen, dass die Applikation beherbergt.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, das sich das Dateiformat der Indizes mit dem Versionssprung von MapServer von 3.6 auf 4.0 geändert hat, sodass die neue Version nicht mit Ihren alten Indizes anfangen kann. Erzeugen Sie bei einer Migration auf die neue Version Ihre Indizes neu.&lt;br /&gt;
&lt;br /&gt;
==shptreevis==\index{shptreevis}&lt;br /&gt;
&lt;br /&gt;
Ein kleines Visualisierungswerkzeug für die Indizes, die mit =shptree=  erzeugt worden sind. Es erzeugt wiederum ein Shapefile, das die Gebiete, in die die indizierten Daten eingeteilt worden sind, enhält.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shptreevis shapefile neu.shp &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können dieses Shapefile natürlich auch wieder als eigenen Layer in ihre Karte einbinden. Die Flächen in dem Shapefile befinden sich allesamt innerhalb der Extents der Ursprungskarte.&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge der GDAL-Bibliothek=&lt;br /&gt;
&lt;br /&gt;
Aus der Vielzahl kleiner Werkzeuge der GDAL-Bibliothek sticht vor allen Dingen =gdaltindex=  hervor, mit dem sich Kataloge für Rasterdaten erstellen lassen können.&lt;br /&gt;
&lt;br /&gt;
==gdaltindex==(3)\index{gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Der Umgang mit Katalogen für Rasterdaten ist in Abschnitt~\ref{text:mapfile:catalogs} beschrieben. Das Format dieser Kataloge ist propretär, d.\,h. Sie werden wohl keine andere Software finden, die mit dieser Art von Katalog etwas anfangen kann.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir an, sie haben in einem Unterverzeichnis =luftbilder=  einige Bilder im ''.tif'' -Format samt Worldfiles abgelegt, die Sie in einem Katalog zusammenfassen möchten. Der Aufruf von =gdaltindex=  könnte dann zum Beispiel folgendermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex -tileindex IMAGE index.shp luftbilder/*.tif&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =tileindex=  wird die Spalte in der ''.dbf'' -Datei bestimmt, die den Namen der Bild-Files enthalten soll. Es folgt der Name des zu erstellenden Index, und natürlich die Namen der georeferenzierten Daten, für die der Katalog erstellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie auch nach Erstellung des Katalogs immer noch die Worldfiles für die Daten vorhalten müssen, obwohl ja eigentlich eben diese Angaben jetzt im Katalog stehen sollten.&lt;br /&gt;
&lt;br /&gt;
Ebenfalls zu beachten sind =OFFSITE= -Angaben des Layers im Mapfile, in dem der Bildkatalog eingebunden werden soll. Da für diesen Parameter der Index der Farbe in der Farbpalette der Bilder angegeben werden muß, der transparent geschaltet werden soll, muß peinlichst genau darauf geachtet werden, dass alle Bilder im Katalog die gleiche Farbpalette haben, beziehungsweise dass sie alle die transparente Farbe an der gleichen Stelle in der Palette haben müssen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{FAQ}\index{FAQ}(1)&lt;br /&gt;
&lt;br /&gt;
=fehlermeldungen=&lt;br /&gt;
&lt;br /&gt;
==projection: system file not found==&lt;br /&gt;
&lt;br /&gt;
=verhalten=&lt;br /&gt;
&lt;br /&gt;
==kein bild im browser==&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_7&amp;diff=34435</id>
		<title>HBUMNMapServer ger Capter 7</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_7&amp;diff=34435"/>
		<updated>2009-01-23T10:21:47Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Werkzeuge des MapServers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Zusätzliche Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Viele kleine Werkzeuge stehen bereit, die das Drumherum um eine (potenzielle) MapServer-Anwendung anreichern. Und einige sind sogar ziemlich nützlich. Im folgenden sollen die Kommandozeilenwerkzeuge besprochen werden, die in den Quellcodepaketen der Shapelib, des MapServers und der Bibliothek GDAL bzw. OGR zu finden sind.&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge der Bibliothek Shapelib=\index{Shapelib}&lt;br /&gt;
&lt;br /&gt;
Diese Bibliothek wird auch vom MapServer verwendet, nämlich um -- wenig überraschend -- mit Shapefiles umzugehen. Allerdings wird dabei keine im System installierte Shapelib benutzt. Der MapServer bringt die entsprechenden Dateien in seinem eigenen Quellcodepaket mit.&lt;br /&gt;
&lt;br /&gt;
Das gilt jedoch leider nicht für die ganzen Werkzeuge der Shapelib. Möchte man also die Vorteile dieser kleinen Tools genießen, muß man es auf sich nehmen und die Shapelib extra kompilieren und installieren. Das ist schnell und einfach getan, indem man das Paket auspackt, in das neu entstandene Verzeichnis wechselt und mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # make&lt;br /&gt;
 # cd contrib&lt;br /&gt;
 # make&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
das Ganze hinter sich bringt.&lt;br /&gt;
&lt;br /&gt;
Man hat dann sowohl im Hauptverzeichnis des Quelltextes als auch im Unterverzeichnis =contrib=  jeweils einige kleine Programme, die man sich an entsprechende Stellen im System kopieren muß. Das Verzeichnis =/usr/local/bin=  kommt auf Unix-Systemen gerne zum Einsatz.&lt;br /&gt;
&lt;br /&gt;
==shpdump==\index{shpdump}&lt;br /&gt;
&lt;br /&gt;
Das Programm =shpdump=  gibt den Inhalt eines Shapefiles in Textform auf der Kommandozeile aus. Das sieht für das Shapefile =lakespy2.shp=  aus dem offiziellen Itasca-Demo beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpdump lakespy2.shp&lt;br /&gt;
&lt;br /&gt;
 Shapefile Type: Polygon   # of Shapes: 1379&lt;br /&gt;
&lt;br /&gt;
 File Bounds: (  393234.394, 5208170.531,0,0)&lt;br /&gt;
          to  (  495403.171, 5303964.877,0,0)&lt;br /&gt;
&lt;br /&gt;
 Shape:0 (Polygon)  nVertices=38, nParts=1&lt;br /&gt;
   Bounds:(  404885.933, 5292677.993, 0, 0)&lt;br /&gt;
       to (  405418.198, 5293262.006, 0, 0)&lt;br /&gt;
      (  405040.809, 5292726.997, 0, 0) Ring &lt;br /&gt;
      (  404949.931, 5292756.498, 0, 0)  &lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besonders schön ist die Angabe der Bounding Box ganz zu Beginn, da man auf diese Weise schnell die Extents eines Shapefiles in Erfahrung bringen kann.&lt;br /&gt;
&lt;br /&gt;
==shpcreate, shpadd, dbfcreate und dbfadd==\index{shpcreate}\index{shpadd}\index{dbfcreate}\index{dbfadd}&lt;br /&gt;
&lt;br /&gt;
Was diese Programme tun, kann man bereits aus ihrem Namen ersehen, und der geneigte Leser mag sich fragen, wer auf die Idee kommt, auf der Kommandozeile von Hand Shapefiles zu erstellen bzw. diesen Shapfiles von Hand Shapes hinzuzufügen?&lt;br /&gt;
&lt;br /&gt;
Diese Frage fußt auf einem Mißverständnis, dem viele Menschen erliegen, die es nicht gewohnt sind, auf der Kommandozeile zu arbeiten. Tatsächlich benutzt man dieses Programm eher selten von Hand. Viel häufiger werden solche Werkzeuge als Kommandos in Skripten eingesetzt, wo sie ihre ganze Macht entfalten können.&lt;br /&gt;
&lt;br /&gt;
Das Programm =shpcreate=  erstellt eine neue Shapedatei, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpcreate bla.shp polygon&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise wird ein leeres Polygon-Shapefile kreiert. Beachten Sie, dass das noch nicht die dazugehörige ''.dbf'' -Datei beinhaltet! Mögliche Shapefiletypen sind =point= , =arc= , =polygon=  und =multipoint= .&lt;br /&gt;
&lt;br /&gt;
Das hinzufügen von Punkten zu diesem neuen Shapefile ist ganz einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpadd bla.shp 1000 2000 2000 3000 3000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird dem Shapefile ein einzelnes Shape mit drei Punkten hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Natürlich möchte man seinem Shapefile auch eine ''.dbf'' -Datei an die Seite stellen. Das kann mit =dbfcreate=  geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfcreate bla.dbf -s NAME 20 -n FLAECHE 10 5&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese ''.dbf'' -Datei erhält zwei Spalten; als erstes eine 20 Zeichen große String-Spalte, und danach eine Spalte für numerische Einträge mit 10 Stellen, von denen 5 Nachkommastellen sind. Mehr Optionen gibt es für dieses Programm auch nicht.&lt;br /&gt;
&lt;br /&gt;
Sodann sollen der Datei selbstverständlich auch Daten hinzufügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfadd bla.dbf Mesopotamien 20.4&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise Daten, die man aus anderen Datenquellen hat, bequem in einem Skript automatisch in ein Shapefile umwandeln.&lt;br /&gt;
&lt;br /&gt;
==dbfdump==\index{dbfdump}&lt;br /&gt;
&lt;br /&gt;
Diese kleine Tool macht für ''.dbf'' -Dateien überraschenderweise das, was =shpdump=  für Shapefiles tut. Eine kleine Beispielausgabe anhand der Datei =airports.dbf=  aus dem offiziellen Itasca-Demo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfdump -h airports.dbf&lt;br /&gt;
 Field 0: Type=String, Title=`NAME', Width=64, Decimals=0&lt;br /&gt;
 Field 1: Type=Double, Title=`LAT', Width=12, Decimals=4&lt;br /&gt;
 Field 2: Type=Double, Title=`LON', Width=12, Decimals=4&lt;br /&gt;
 Field 3: Type=Double, Title=`ELEVATION', Width=12, Decimals=4&lt;br /&gt;
 Field 4: Type=String, Title=`QUADNAME', Width=32, Decimals=0&lt;br /&gt;
 NAME                      LAT      LON       ELEVATION QUADNAME&lt;br /&gt;
 Bigfork Municipal Airport 47.7789  -93.6500  1343.0000 Effie&lt;br /&gt;
 Bolduc Seaplane Base      47.5975  -93.4106  1325.0000 Balsam Lake&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Parameter =-h=  weist das Programm an, zusätzlich noch die Header-Informationen für die Datei auszugeben.&lt;br /&gt;
&lt;br /&gt;
==shpinfo==\index{shpinfo}&lt;br /&gt;
&lt;br /&gt;
Dieses kleine Programm gibt einige grundlegende Informationen über ein Shapefile aus. Am Beispiel der Datei ''airports.shp''  aus dem offiziellen Itasca County-Demo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpinfo airports.shp&lt;br /&gt;
 Info for airports.shp&lt;br /&gt;
 Point(1), 12 Records in file&lt;br /&gt;
 File Bounds: (              0,              0)&lt;br /&gt;
 (         496393,        5291930)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir haben also ein Punkt-Shapefile mit 12 Shapes vor uns.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass dieses Programm als minX/minY-Koordinaten selten etwas anderes ausgibt als 0/0, und für minimale Koordinaten daher nicht wirklich geeignet ist.&lt;br /&gt;
&lt;br /&gt;
==dbfinfo==\index{dbfinfo}&lt;br /&gt;
&lt;br /&gt;
Was ''shpinfo''  für Shapedateien ist, ist dieses Werkzeug für die dazugehörigen ''.dbf'' -Datensätze. Eine Beispielausgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# dbfinfo airports.dbf&lt;br /&gt;
 Info for airports.dbf&lt;br /&gt;
 5 Columns,  12 Records in file&lt;br /&gt;
            NAME	         string  (64,0)&lt;br /&gt;
             LAT	          float  (12,4)&lt;br /&gt;
             LON	          float  (12,4)&lt;br /&gt;
       ELEVATION	          float  (12,4)&lt;br /&gt;
        QUADNAME	         string  (32,0)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge des MapServers=&lt;br /&gt;
&lt;br /&gt;
Nach dem Kompilieren des MapServers findet man im Quellverzeichnis das eine oder andere kleine Werkzeug. Zwei sollen uns im folgenden besonders interessieren.&lt;br /&gt;
&lt;br /&gt;
==shp2img==\index{shp2img}&lt;br /&gt;
&lt;br /&gt;
Dieses Programm ist im wesentlichen MapServer für die Kommandozeile. Der Aufruf sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shp2img -m mapfile.map -i PNG -e 13.0 44.5 33.3 59.6&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird das entsprechende Mapfile dazu benutzt, ein PNG-Bild mit den angegebenen Extents zu erzeugen. Die Kartendarstellung wird dabei aus =mapfile.amp=  bezogen.&lt;br /&gt;
&lt;br /&gt;
Sie können dieses Programm beispielsweise dann benutzen, wenn Sie keinen Zugriff auf einen im Webserver installierten MapServer haben können oder möchten. Es eignet vor allen Dingen zum Debuggen von Mapfiles auf Systemen ohne MapServer.&lt;br /&gt;
&lt;br /&gt;
Alle möglichen Kommandozeileparameter werden durch einen Aufruf von =shp2img=  ohne Optionen ausgegeben.&lt;br /&gt;
&lt;br /&gt;
==shptree==\index{shptree}(2)&lt;br /&gt;
&lt;br /&gt;
Wenn eine Karte gezeichnet werden soll, muß theoretisch jedes einzelne Shape in einem Shapefile darauf geprüft werden, ob es tatsächlich angezeigt werden soll. Das kann offensichtlich sehr zeitaufwendig sein.&lt;br /&gt;
&lt;br /&gt;
Das Werkzeug ''shptree''  schafft hier Abhilfe, indem es einen so genannten Quadtree-Index über den Inhalt des Shapfiles erzeugt. Die Idee ist, dass man das gesamte Shapfile in vier verschiedene Gebiete zerlegt, die ihrerseits wiederum zerlegt werden, und so weiter. Diese Art der Zerlegung wird in einer Indexdatei mit der Endung ''.qix''  gespeichert.&lt;br /&gt;
&lt;br /&gt;
Wenn nun eine Karte generiert werden soll, werden zuallererst Vergleiche mit dem Index angestellt, um herauszufinden, auf welche Shapes man sich bei der Darstellung überhaupt konzentrieren soll. Gerade bei großen Datenmengen kann sich die Geschwindigkeit des MapServers dabei signifikant erhöhen. Beachten Sie jedoch, dass sich dieser Index ausschließlich auf die Vektordaten im Shapfile bezieht und keine Geschwindigkeitsverbesserung für zum Beispiel Attributanfragen liefert.&lt;br /&gt;
&lt;br /&gt;
Das Programm wird normalerweise sehr simpel angewendet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shptree shapefile.shp&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt noch zwei weitere Optionen für das Programm, der genaue Aufruf wird definiert als&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 shptree [shapefile] &amp;lt;tiefe&amp;gt; &amp;lt;byteorder&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Tiefe ist die Tiefe des Baumes gemeint, der erzeugt werden soll. Davon hat diese Art von Index auch ihren Namen. Man kann sich die Unterteilung des Shapfiles auch als Verzweigung in verschiedene Äste vorstellen, die sich dann wieder verzweigen und so weiter.&lt;br /&gt;
&lt;br /&gt;
Die Byteorder ist eine kleine informatische Spezialität. Alle Daten werden als Bits gespeichert, und 8 solcher Bits werden zu einem Byte zusammengefaßt. 'Normale' ganzzahlige Werte sind auf Intel-Computern beispielsweise 4 Byte lang. Unterschiedlich ist aber nicht nur die Menge an Platz, die Zahlen einnehmen können, sondern auch wie sie abgespeichert werden. Ohne weiter ins Detail gehen zu wollen: es gibt verschiedene Ansätze, beispielsweise zuerst das niederwertigste Bit in einem Byte zu speichern und die anderen dahinter anzuordnen -- oder aber umgekehrt. Diese Ansätze unterscheiden sich von Plattform zu Plattform.&lt;br /&gt;
&lt;br /&gt;
Rufen Sie einmal das Programm ohne jeden Parameter auf, um eine Liste der möglichen Byteorders zu Gesicht zu bekommen. Generell kann man sagen, dass es am sinnvollsten ist, keine Byteorder anzugeben und das Programm shptree ganz einfach einmal für alle Daten auf dem Zielsystem aufzurufen, dass die Applikation beherbergt.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, das sich das Dateiformat der Indizes mit dem Versionssprung von MapServer von 3.6 auf 4.0 geändert hat, sodass die neue Version nicht mit Ihren alten Indizes anfangen kann. Erzeugen Sie bei einer Migration auf die neue Version Ihre Indizes neu.&lt;br /&gt;
&lt;br /&gt;
==shptreevis==\index{shptreevis}&lt;br /&gt;
&lt;br /&gt;
Ein kleines Visualisierungswerkzeug für die Indizes, die mit =shptree=  erzeugt worden sind. Es erzeugt wiederum ein Shapefile, das die Gebiete, in die die indizierten Daten eingeteilt worden sind, enhält.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shptreevis shapefile neu.shp &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können dieses Shapefile natürlich auch wieder als eigenen Layer in ihre Karte einbinden. Die Flächen in dem Shapefile befinden sich allesamt innerhalb der Extents der Ursprungskarte.&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge der GDAL-Bibliothek=&lt;br /&gt;
&lt;br /&gt;
Aus der Vielzahl kleiner Werkzeuge der GDAL-Bibliothek sticht vor allen Dingen =gdaltindex=  hervor, mit dem sich Kataloge für Rasterdaten erstellen lassen können.&lt;br /&gt;
&lt;br /&gt;
==gdaltindex==(3)\index{gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Der Umgang mit Katalogen für Rasterdaten ist in Abschnitt~\ref{text:mapfile:catalogs} beschrieben. Das Format dieser Kataloge ist propretär, d.\,h. Sie werden wohl keine andere Software finden, die mit dieser Art von Katalog etwas anfangen kann.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir an, sie haben in einem Unterverzeichnis =luftbilder=  einige Bilder im ''.tif'' -Format samt Worldfiles abgelegt, die Sie in einem Katalog zusammenfassen möchten. Der Aufruf von =gdaltindex=  könnte dann zum Beispiel folgendermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex -tileindex IMAGE index.shp luftbilder/*.tif&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =tileindex=  wird die Spalte in der ''.dbf'' -Datei bestimmt, die den Namen der Bild-Files enthalten soll. Es folgt der Name des zu erstellenden Index, und natürlich die Namen der georeferenzierten Daten, für die der Katalog erstellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie auch nach Erstellung des Katalogs immer noch die Worldfiles für die Daten vorhalten müssen, obwohl ja eigentlich eben diese Angaben jetzt im Katalog stehen sollten.&lt;br /&gt;
&lt;br /&gt;
Ebenfalls zu beachten sind =OFFSITE= -Angaben des Layers im Mapfile, in dem der Bildkatalog eingebunden werden soll. Da für diesen Parameter der Index der Farbe in der Farbpalette der Bilder angegeben werden muß, der transparent geschaltet werden soll, muß peinlichst genau darauf geachtet werden, dass alle Bilder im Katalog die gleiche Farbpalette haben, beziehungsweise dass sie alle die transparente Farbe an der gleichen Stelle in der Palette haben müssen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{FAQ}\index{FAQ}(1)&lt;br /&gt;
&lt;br /&gt;
=fehlermeldungen=&lt;br /&gt;
&lt;br /&gt;
==projection: system file not found==&lt;br /&gt;
&lt;br /&gt;
=verhalten=&lt;br /&gt;
&lt;br /&gt;
==kein bild im browser==&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_7&amp;diff=34434</id>
		<title>HBUMNMapServer ger Capter 7</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_7&amp;diff=34434"/>
		<updated>2009-01-23T10:20:29Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Zusätzliche Werkzeuge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Zusätzliche Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Viele kleine Werkzeuge stehen bereit, die das Drumherum um eine (potenzielle) MapServer-Anwendung anreichern. Und einige sind sogar ziemlich nützlich. Im folgenden sollen die Kommandozeilenwerkzeuge besprochen werden, die in den Quellcodepaketen der Shapelib, des MapServers und der Bibliothek GDAL bzw. OGR zu finden sind.&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge der Bibliothek Shapelib=\index{Shapelib}&lt;br /&gt;
&lt;br /&gt;
Diese Bibliothek wird auch vom MapServer verwendet, nämlich um -- wenig überraschend -- mit Shapefiles umzugehen. Allerdings wird dabei keine im System installierte Shapelib benutzt. Der MapServer bringt die entsprechenden Dateien in seinem eigenen Quellcodepaket mit.&lt;br /&gt;
&lt;br /&gt;
Das gilt jedoch leider nicht für die ganzen Werkzeuge der Shapelib. Möchte man also die Vorteile dieser kleinen Tools genießen, muß man es auf sich nehmen und die Shapelib extra kompilieren und installieren. Das ist schnell und einfach getan, indem man das Paket auspackt, in das neu entstandene Verzeichnis wechselt und mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # make&lt;br /&gt;
 # cd contrib&lt;br /&gt;
 # make&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
das Ganze hinter sich bringt.&lt;br /&gt;
&lt;br /&gt;
Man hat dann sowohl im Hauptverzeichnis des Quelltextes als auch im Unterverzeichnis =contrib=  jeweils einige kleine Programme, die man sich an entsprechende Stellen im System kopieren muß. Das Verzeichnis =/usr/local/bin=  kommt auf Unix-Systemen gerne zum Einsatz.&lt;br /&gt;
&lt;br /&gt;
==shpdump==\index{shpdump}&lt;br /&gt;
&lt;br /&gt;
Das Programm =shpdump=  gibt den Inhalt eines Shapefiles in Textform auf der Kommandozeile aus. Das sieht für das Shapefile =lakespy2.shp=  aus dem offiziellen Itasca-Demo beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpdump lakespy2.shp&lt;br /&gt;
&lt;br /&gt;
 Shapefile Type: Polygon   # of Shapes: 1379&lt;br /&gt;
&lt;br /&gt;
 File Bounds: (  393234.394, 5208170.531,0,0)&lt;br /&gt;
          to  (  495403.171, 5303964.877,0,0)&lt;br /&gt;
&lt;br /&gt;
 Shape:0 (Polygon)  nVertices=38, nParts=1&lt;br /&gt;
   Bounds:(  404885.933, 5292677.993, 0, 0)&lt;br /&gt;
       to (  405418.198, 5293262.006, 0, 0)&lt;br /&gt;
      (  405040.809, 5292726.997, 0, 0) Ring &lt;br /&gt;
      (  404949.931, 5292756.498, 0, 0)  &lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besonders schön ist die Angabe der Bounding Box ganz zu Beginn, da man auf diese Weise schnell die Extents eines Shapefiles in Erfahrung bringen kann.&lt;br /&gt;
&lt;br /&gt;
==shpcreate, shpadd, dbfcreate und dbfadd==\index{shpcreate}\index{shpadd}\index{dbfcreate}\index{dbfadd}&lt;br /&gt;
&lt;br /&gt;
Was diese Programme tun, kann man bereits aus ihrem Namen ersehen, und der geneigte Leser mag sich fragen, wer auf die Idee kommt, auf der Kommandozeile von Hand Shapefiles zu erstellen bzw. diesen Shapfiles von Hand Shapes hinzuzufügen?&lt;br /&gt;
&lt;br /&gt;
Diese Frage fußt auf einem Mißverständnis, dem viele Menschen erliegen, die es nicht gewohnt sind, auf der Kommandozeile zu arbeiten. Tatsächlich benutzt man dieses Programm eher selten von Hand. Viel häufiger werden solche Werkzeuge als Kommandos in Skripten eingesetzt, wo sie ihre ganze Macht entfalten können.&lt;br /&gt;
&lt;br /&gt;
Das Programm =shpcreate=  erstellt eine neue Shapedatei, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpcreate bla.shp polygon&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise wird ein leeres Polygon-Shapefile kreiert. Beachten Sie, dass das noch nicht die dazugehörige ''.dbf'' -Datei beinhaltet! Mögliche Shapefiletypen sind =point= , =arc= , =polygon=  und =multipoint= .&lt;br /&gt;
&lt;br /&gt;
Das hinzufügen von Punkten zu diesem neuen Shapefile ist ganz einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpadd bla.shp 1000 2000 2000 3000 3000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird dem Shapefile ein einzelnes Shape mit drei Punkten hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Natürlich möchte man seinem Shapefile auch eine ''.dbf'' -Datei an die Seite stellen. Das kann mit =dbfcreate=  geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfcreate bla.dbf -s NAME 20 -n FLAECHE 10 5&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese ''.dbf'' -Datei erhält zwei Spalten; als erstes eine 20 Zeichen große String-Spalte, und danach eine Spalte für numerische Einträge mit 10 Stellen, von denen 5 Nachkommastellen sind. Mehr Optionen gibt es für dieses Programm auch nicht.&lt;br /&gt;
&lt;br /&gt;
Sodann sollen der Datei selbstverständlich auch Daten hinzufügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfadd bla.dbf Mesopotamien 20.4&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise Daten, die man aus anderen Datenquellen hat, bequem in einem Skript automatisch in ein Shapefile umwandeln.&lt;br /&gt;
&lt;br /&gt;
==dbfdump==\index{dbfdump}&lt;br /&gt;
&lt;br /&gt;
Diese kleine Tool macht für ''.dbf'' -Dateien überraschenderweise das, was =shpdump=  für Shapefiles tut. Eine kleine Beispielausgabe anhand der Datei =airports.dbf=  aus dem offiziellen Itasca-Demo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # dbfdump -h airports.dbf&lt;br /&gt;
 Field 0: Type=String, Title=`NAME', Width=64, Decimals=0&lt;br /&gt;
 Field 1: Type=Double, Title=`LAT', Width=12, Decimals=4&lt;br /&gt;
 Field 2: Type=Double, Title=`LON', Width=12, Decimals=4&lt;br /&gt;
 Field 3: Type=Double, Title=`ELEVATION', Width=12, Decimals=4&lt;br /&gt;
 Field 4: Type=String, Title=`QUADNAME', Width=32, Decimals=0&lt;br /&gt;
 NAME                      LAT      LON       ELEVATION QUADNAME&lt;br /&gt;
 Bigfork Municipal Airport 47.7789  -93.6500  1343.0000 Effie&lt;br /&gt;
 Bolduc Seaplane Base      47.5975  -93.4106  1325.0000 Balsam Lake&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Parameter =-h=  weist das Programm an, zusätzlich noch die Header-Informationen für die Datei auszugeben.&lt;br /&gt;
&lt;br /&gt;
==shpinfo==\index{shpinfo}&lt;br /&gt;
&lt;br /&gt;
Dieses kleine Programm gibt einige grundlegende Informationen über ein Shapefile aus. Am Beispiel der Datei ''airports.shp''  aus dem offiziellen Itasca County-Demo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shpinfo airports.shp&lt;br /&gt;
 Info for airports.shp&lt;br /&gt;
 Point(1), 12 Records in file&lt;br /&gt;
 File Bounds: (              0,              0)&lt;br /&gt;
 (         496393,        5291930)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir haben also ein Punkt-Shapefile mit 12 Shapes vor uns.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass dieses Programm als minX/minY-Koordinaten selten etwas anderes ausgibt als 0/0, und für minimale Koordinaten daher nicht wirklich geeignet ist.&lt;br /&gt;
&lt;br /&gt;
==dbfinfo==\index{dbfinfo}&lt;br /&gt;
&lt;br /&gt;
Was ''shpinfo''  für Shapedateien ist, ist dieses Werkzeug für die dazugehörigen ''.dbf'' -Datensätze. Eine Beispielausgabe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# dbfinfo airports.dbf&lt;br /&gt;
 Info for airports.dbf&lt;br /&gt;
 5 Columns,  12 Records in file&lt;br /&gt;
            NAME	         string  (64,0)&lt;br /&gt;
             LAT	          float  (12,4)&lt;br /&gt;
             LON	          float  (12,4)&lt;br /&gt;
       ELEVATION	          float  (12,4)&lt;br /&gt;
        QUADNAME	         string  (32,0)&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge des MapServers=&lt;br /&gt;
&lt;br /&gt;
Nach dem Kompilieren des MapServers findet man im Quellverzeichnis das eine oder andere kleine Werkzeug. Zwei sollen uns im folgenden besonders interessieren.&lt;br /&gt;
&lt;br /&gt;
==shp2img==\index{shp2img}&lt;br /&gt;
&lt;br /&gt;
Dieses Programm ist im wesentlichen MapServer für die Kommandozeile. Der Aufruf sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# shp2img -m mapfile.map -i PNG -e 13.0 44.5 33.3 59.6&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird das entsprechende Mapfile dazu benutzt, ein PNG-Bild mit den angegebenen Extents zu erzeugen. Die Kartendarstellung wird dabei aus =mapfile.amp=  bezogen.&lt;br /&gt;
&lt;br /&gt;
Sie können dieses Programm beispielsweise dann benutzen, wenn Sie keinen Zugriff auf einen im Webserver installierten MapServer haben können oder möchten. Es eignet vor allen Dingen zum Debuggen von Mapfiles auf Systemen ohne MapServer.&lt;br /&gt;
&lt;br /&gt;
Alle möglichen Kommandozeileparameter werden durch einen Aufruf von =shp2img=  ohne Optionen ausgegeben.&lt;br /&gt;
&lt;br /&gt;
==shptree==\index{shptree}(2)&lt;br /&gt;
&lt;br /&gt;
Wenn eine Karte gezeichnet werden soll, muß theoretisch jedes einzelne Shape in einem Shapefile darauf geprüft werden, ob es tatsächlich angezeigt werden soll. Das kann offensichtlich sehr zeitaufwendig sein.&lt;br /&gt;
&lt;br /&gt;
Das Werkzeug ''shptree''  schafft hier Abhilfe, indem es einen so genannten Quadtree-Index über den Inhalt des Shapfiles erzeugt. Die Idee ist, dass man das gesamte Shapfile in vier verschiedene Gebiete zerlegt, die ihrerseits wiederum zerlegt werden, und so weiter. Diese Art der Zerlegung wird in einer Indexdatei mit der Endung ''.qix''  gespeichert.&lt;br /&gt;
&lt;br /&gt;
Wenn nun eine Karte generiert werden soll, werden zuallererst Vergleiche mit dem Index angestellt, um herauszufinden, auf welche Shapes man sich bei der Darstellung überhaupt konzentrieren soll. Gerade bei großen Datenmengen kann sich die Geschwindigkeit des MapServers dabei signifikant erhöhen. Beachten Sie jedoch, dass sich dieser Index ausschließlich auf die Vektordaten im Shapfile bezieht und keine Geschwindigkeitsverbesserung für zum Beispiel Attributanfragen liefert.&lt;br /&gt;
&lt;br /&gt;
Das Programm wird normalerweise sehr simpel angewendet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# shptree shapefile.shp&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt noch zwei weitere Optionen für das Programm, der genaue Aufruf wird definiert als&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
shptree [shapefile] &amp;lt;tiefe&amp;gt; &amp;lt;byteorder&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Tiefe ist die Tiefe des Baumes gemeint, der erzeugt werden soll. Davon hat diese Art von Index auch ihren Namen. Man kann sich die Unterteilung des Shapfiles auch als Verzweigung in verschiedene Äste vorstellen, die sich dann wieder verzweigen und so weiter.&lt;br /&gt;
&lt;br /&gt;
Die Byteorder ist eine kleine informatische Spezialität. Alle Daten werden als Bits gespeichert, und 8 solcher Bits werden zu einem Byte zusammengefaßt. 'Normale' ganzzahlige Werte sind auf Intel-Computern beispielsweise 4 Byte lang. Unterschiedlich ist aber nicht nur die Menge an Platz, die Zahlen einnehmen können, sondern auch wie sie abgespeichert werden. Ohne weiter ins Detail gehen zu wollen: es gibt verschiedene Ansätze, beispielsweise zuerst das niederwertigste Bit in einem Byte zu speichern und die anderen dahinter anzuordnen -- oder aber umgekehrt. Diese Ansätze unterscheiden sich von Plattform zu Plattform.&lt;br /&gt;
&lt;br /&gt;
Rufen Sie einmal das Programm ohne jeden Parameter auf, um eine Liste der möglichen Byteorders zu Gesicht zu bekommen. Generell kann man sagen, dass es am sinnvollsten ist, keine Byteorder anzugeben und das Programm shptree ganz einfach einmal für alle Daten auf dem Zielsystem aufzurufen, dass die Applikation beherbergt.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, das sich das Dateiformat der Indizes mit dem Versionssprung von MapServer von 3.6 auf 4.0 geändert hat, sodass die neue Version nicht mit Ihren alten Indizes anfangen kann. Erzeugen Sie bei einer Migration auf die neue Version Ihre Indizes neu.&lt;br /&gt;
&lt;br /&gt;
==shptreevis==\index{shptreevis}&lt;br /&gt;
&lt;br /&gt;
Ein kleines Visualisierungswerkzeug für die Indizes, die mit =shptree=  erzeugt worden sind. Es erzeugt wiederum ein Shapefile, das die Gebiete, in die die indizierten Daten eingeteilt worden sind, enhält.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# shptreevis shapefile neu.shp &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können dieses Shapefile natürlich auch wieder als eigenen Layer in ihre Karte einbinden. Die Flächen in dem Shapefile befinden sich allesamt innerhalb der Extents der Ursprungskarte.&lt;br /&gt;
&lt;br /&gt;
=Werkzeuge der GDAL-Bibliothek=&lt;br /&gt;
&lt;br /&gt;
Aus der Vielzahl kleiner Werkzeuge der GDAL-Bibliothek sticht vor allen Dingen =gdaltindex=  hervor, mit dem sich Kataloge für Rasterdaten erstellen lassen können.&lt;br /&gt;
&lt;br /&gt;
==gdaltindex==(3)\index{gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Der Umgang mit Katalogen für Rasterdaten ist in Abschnitt~\ref{text:mapfile:catalogs} beschrieben. Das Format dieser Kataloge ist propretär, d.\,h. Sie werden wohl keine andere Software finden, die mit dieser Art von Katalog etwas anfangen kann.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir an, sie haben in einem Unterverzeichnis =luftbilder=  einige Bilder im ''.tif'' -Format samt Worldfiles abgelegt, die Sie in einem Katalog zusammenfassen möchten. Der Aufruf von =gdaltindex=  könnte dann zum Beispiel folgendermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex -tileindex IMAGE index.shp luftbilder/*.tif&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =tileindex=  wird die Spalte in der ''.dbf'' -Datei bestimmt, die den Namen der Bild-Files enthalten soll. Es folgt der Name des zu erstellenden Index, und natürlich die Namen der georeferenzierten Daten, für die der Katalog erstellt werden soll.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie auch nach Erstellung des Katalogs immer noch die Worldfiles für die Daten vorhalten müssen, obwohl ja eigentlich eben diese Angaben jetzt im Katalog stehen sollten.&lt;br /&gt;
&lt;br /&gt;
Ebenfalls zu beachten sind =OFFSITE= -Angaben des Layers im Mapfile, in dem der Bildkatalog eingebunden werden soll. Da für diesen Parameter der Index der Farbe in der Farbpalette der Bilder angegeben werden muß, der transparent geschaltet werden soll, muß peinlichst genau darauf geachtet werden, dass alle Bilder im Katalog die gleiche Farbpalette haben, beziehungsweise dass sie alle die transparente Farbe an der gleichen Stelle in der Palette haben müssen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{FAQ}\index{FAQ}(1)&lt;br /&gt;
&lt;br /&gt;
=fehlermeldungen=&lt;br /&gt;
&lt;br /&gt;
==projection: system file not found==&lt;br /&gt;
&lt;br /&gt;
=verhalten=&lt;br /&gt;
&lt;br /&gt;
==kein bild im browser==&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_6&amp;diff=34433</id>
		<title>HBUMNMapServer ger Capter 6</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_6&amp;diff=34433"/>
		<updated>2009-01-23T10:17:59Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Formulareingaben in PHP verarbeiten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= MapScript =&lt;br /&gt;
(1)\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
Bisher haben Sie den MapServer als Applikation kennengelernt, die in einem Webserver wie zum Beispiel Apache arbeitet, und direkt über Parameter des URL aufgerufen und in ihrem Verhalten beeinflußt werden kann.&lt;br /&gt;
&lt;br /&gt;
Man kann sich aber natürlich auch vorstellen, die Funktionen von MapServer -- das Lesen von Mapfiles, das Rendern der Karten und so weiter -- auch aus eigenen Programmen nutzen zu wollen, natürlich auch solchen, die nicht in einem Webserver laufen sollen. Dazu müßte man diese Funktionen separat zur Verfügung stellen, beispielsweise in einer eigenen Bibliothek, auf die dann aus anderen Programmiersprachen zugegriffen werden kann. Diese Bibliothek existiert bereits und trägt den Namen MapScript.&lt;br /&gt;
&lt;br /&gt;
Zu den Sprachen wie Java, Python, Perl und einigen anderen, die mit MapScript benutzt werden können, gesellt sich auch PHP. PHP MapScript soll im Folgenden als Anknüpfungspunkt für die Erklärung von MapScript dienen -- die genaue Terminologie für einzelne Programmiersprachen entnehmen Sie bitte der jeweilgen Dokumentation der Sprache bzw. den Beispielen, die dem MapServer-Quellcode beiliegen.&lt;br /&gt;
&lt;br /&gt;
=PHP MapScript=(2)\index{PHP MapScript}\index{MapScript!PHP}&lt;br /&gt;
&lt;br /&gt;
Ich erspare dem Leser die an dieser Stelle üblichen Hymnen auf PHP\footnote{Beziehungsweise die üblichen Flames. Die Sprache ist definitiv nichts für Puristen oder Entwickler mit eng gesteckten Vorgaben, was den Resourcenverbrauch angeht.} und seine Flexibilität als Sprache für Webanwendungen. Es ist in der Tat sehr weit verbreitet. Das ist (neben der besonderen Pflege, die gerade diese Sprachanbindung erfährt) auch der Grund, warum wir an dieser Stelle detailliert auf PHP MapScript eingehen, und nicht beispielsweise auf Perl.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle gehen wir nicht darauf ein, wie Sie PHP installieren, oder wie Sie Ihren Webserver korrekt für den Einsatz von PHP konfigurieren. Wie man das tut, erfahren Sie in der Dokumentation von PHP bzw. Ihres Webservers. Die Installation von PHP MapScript wird im Anhang dieses Handbuches abgehandelt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass PHP MapScript im Moment zwingend voraussetzt, dass Sie PHP ''nicht''  als Modul laden, sondern als CGI-Programm einsetzen. Es kann ansonsten zu nicht vorhersehbaren Komplikationen kommen.&lt;br /&gt;
&lt;br /&gt;
Als erstes deutschsprachiges Einsteigerbuch zu PHP eignet sich beispielsweise~[[theis:2000:php]]; allerdings gibt es eine solche Unzahl an Büchern über diese Sprache, dass eine persönliche Auswahl im Buchladen erfolgen sollte. Die Website zur PHP [[http:website:php]] stellt ausführliche Dokumentation bereits, die interessanterweise auch vollständig ins deutsche übersetzt ist.&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist es eine gute Idee, sich mit der FAQ von =de.comp.lang.php= ~[[faq:dclp]]  auseinanderzusetzen, der deutschsprachigen Newsgroup zu PHP, die in einem eigenen Kapitel auch auf Sicherheitsbelange eingeht.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{mapscript-hyk}{Ein Beispiel für eine PHP MapScript Anwendung sind die Hydrogeologischen Karten Brandenburg}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
==Laden des Moduls==&lt;br /&gt;
&lt;br /&gt;
Um die MapScript-Funktionen in einer PHP-Seite verwenden zu können, muss das Modul dafür geladen werden. Das geschieht ganz einfach durch ''dl'' :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 dl (&amp;quot;php_mapscript.so&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies sollte die erste Zeile sein, die Sie in jede Seite einfügen, die MapScript-Funktionen benutzt. Sollten Sie sich unter Windows befinden, ändert sich diese Zeile leicht in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 dl (&amp;quot;php_mapscript.dll&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine portable Anwendung schreiben sollen, ist es demnach angebracht, gleich zu Beginn des Skripts auf das verwendete Betriebssystem zu prüfen und dann die korrekte Datei zu laden.&lt;br /&gt;
&lt;br /&gt;
==Setzen von Objekt-Eigenschaften==&lt;br /&gt;
&lt;br /&gt;
Bevor Sie auch nur eine einzige Klasse aus MapScript kennenlernen, möchte ich zeigen, wie man die Eigenschaften von Objekten setzt, da diese Methode für alle Objekte (die sie unterstützen) gleich ist.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;layer -&amp;gt; set (&amp;quot;name&amp;quot;, &amp;quot;gruenflaechen&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit diesem Aufruf wird der Name eines Layer-Objektes auf =gruenflaechen=  gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der 'korrekte' objektorientierte Ansatz wäre natürlich gewesen, dafür eine eigene Routine =setName()=  zu implementieren. Da einige Klassen in MapScript jedoch über eine ziemlich große Anzahl an Eigenschaften verfügen, hat man sich auf diese Methode beschränkt.&lt;br /&gt;
&lt;br /&gt;
Das Setzen von Eigenschaften auf diese Weise funktioniert nur für Eigenschaften, die nicht =read-only=  sind. Nicht jedes Objekt implementiert zudem die =set()= -Methode. In der Referenz im Anhang dieses Handbuchs sehen Sie, welche Klasse eine solche Methode zur Verfügung stellt.&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus haben einige Klassen für einige Eigenschaften doch noch eigene Methoden implementiert. Studieren Sie die Referenz im Anhang, um herauszufinden, für welche Klassen und Eigenschaften das gilt.&lt;br /&gt;
&lt;br /&gt;
==Formulareingaben in PHP verarbeiten==&lt;br /&gt;
&lt;br /&gt;
In älteren PHP-Versionen war es kein Problem, URL-Parameter einfach als Variable in ein PHP-Skript zu übernehmen. Wenn ein Aufruf also etwa so aussah:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 .../skript.php?name=Calli&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann konnte man ohne Probleme das folgende in sein Skript schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 echo &amp;lt;/math&amp;gt;name;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das produzierte dann die Ausgabe =Calli= .&lt;br /&gt;
&lt;br /&gt;
In neueren Fassungen von PHP\footnote{Und aufgrund der bekannt gewordenen Sicherheitslücken möchte man eine alte Version nicht benutzen. Verwenden Sie nichts unter 4.3.3!} geht das so nicht mehr. Weil es durch diverse Tricksereien möglich war, globale PHP-Variablen von außen zu überschreiben, und weil man die Programmierer zwingen wollte, sich mit den Werten in ihren Variablen genauer zu befassen, muß man sich jeden Wert nun explizit aus einem Array holen, das den Namen =\&amp;lt;math&amp;gt;_GET[]=  trägt.&lt;br /&gt;
&lt;br /&gt;
Für unser obiges Beispiel benötigen Sie dann also folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;dername = &amp;lt;/math&amp;gt;_GET ['name'];&lt;br /&gt;
 echo &amp;lt;/math&amp;gt;dername;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manchmal werden durch eine Eingabemöglichkeit in einem HTML-Formular mehrere Werte übergeben. Ein Beispiel dafür ist ein angeklicktes Bild, wie es etwa unsere Karte ist -- ein Klick produziert natürlich eine X- und eine Y-Koordinate. PHP verhält sich an dieser Stelle etwas unerwartet. Betrachten wir das folgende Bild in einem HTML-Formular:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;image&amp;quot; name=&amp;quot;img&amp;quot; src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach einem Klick finden Sie im URL zwei Werte, namentlich =img.x=  und =img.y= . Diese beiden Variablen werden Sie aber im Array =\&amp;lt;math&amp;gt;_GET[]=  vergeblich suchen, denn für PHP werden die Punkte durch Unterstriche ersetzt. Sie müssen sich also =img_x=  und =img_y=  aus dem Array holen.&lt;br /&gt;
&lt;br /&gt;
Es ist übrigens immer angezeigt, den Wert jeder Variablen, die von außen belegt wird, eingehend auf seine Sinnhaftigkeit zu prüfen.&lt;br /&gt;
&lt;br /&gt;
==Die mapObj-Klasse==\index{Mapscript!mapObj}\index{mapObj}&lt;br /&gt;
&lt;br /&gt;
Als nächstes möchten wir betrachten, wie MapScript ein Mapfile behandelt. Betrachten Sie das erste Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
 &amp;lt;math&amp;gt;image = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
 &amp;lt;math&amp;gt;imageurl = &amp;lt;/math&amp;gt;image -&amp;gt; saveWebImage (MS_PNG, 1, 1, 0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der ersten Zeile wird ein =mapObj=  erzeugt, das auf ein bereits existentes Mapfile zugreift. Danach wird daraus ein =ImageObj=  erzeugt, es wird also die Karte gezeichnet. Dabei werden die gesetzten Werte für die Extents aus dem Mapfile übernommen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass dadurch noch keine fertige Bild''datei''  erzeugt wird. Die Karte existiert zu diesem Zeitpunkt nur als Puffer im Speicher.&lt;br /&gt;
&lt;br /&gt;
In einer Datei tatsächlich gespeichert wird das Bild in der letzten Zeile, in unserem Beispiel als Bild im PNG-Format. Die Rückgabe der Funktion ist der URL für den Webserver, unter der er das Bild ausliefern kann.&lt;br /&gt;
&lt;br /&gt;
Man kann daher weiter unten in der Seite folgendes HTML verwenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
 &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
 &amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;lt;?php echo &amp;lt;math&amp;gt;imageurl; ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird der betreffende URL in den =&amp;lt;img&amp;gt;= -Tag eingefügt und an den Client ausgeliefert. Das Resultat ist natürlich ein zentriertes Bild der Karte im Webbrowser.&lt;br /&gt;
&lt;br /&gt;
Auf die gleiche Weise werden übrigens auch Legenden, Maßstäbe und Referenzkarten erzeugt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;img_legend = &amp;lt;/math&amp;gt;map -&amp;gt; drawLegend ();&lt;br /&gt;
 &amp;lt;math&amp;gt;img_scalebar = &amp;lt;/math&amp;gt;map -&amp;gt; drawScaleBar ();&lt;br /&gt;
 &amp;lt;math&amp;gt;img_refmap = &amp;lt;/math&amp;gt;map -&amp;gt; drawReferenceMap ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch diese Bildobjekte werden wieder über deren Methode =saveWebImage=  abgespeichert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Zoomen}&lt;br /&gt;
&lt;br /&gt;
Das Zoomen in eine Karte kann auf drei Weisen geschehen: Zoomen in Richtung eines Punktes, Zoomen auf ein Rechteck und Zoomen auf einen Punkt in einem bestimmten Maßstab.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den ersten Fall. Wir gehen davon aus, dass wir ein Bild in einem HTML-Formular eingebettet hatten, und dieses Bild wie gerade beschrieben per PHP Mapscript erzeugt hatten. Wurde das Bild angeklickt, werden die Pixelkoordinaten des Klicks über das Formular mit übergeben. Gehen wir von einem festen Zoomfaktor von 2 aus (diesen Wert legen wir für dieses Beispiel jetzt fest), können wir mit diesen Pixeln folgendes tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/file.map&amp;quot;);&lt;br /&gt;
 &amp;lt;math&amp;gt;map -&amp;gt; zoomPoint (2, &amp;lt;/math&amp;gt;imgxy, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;math&amp;gt;extent);&lt;br /&gt;
 &amp;lt;math&amp;gt;img = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird in seinem ursprünglichen Zustand geladen. Dann werden der Zoomfunktion die nötigen Parameter übergeben: zuerst der Zoomfaktor, den wir hier mit 2 festlegen, aber natürlich auch im Formular einstellen lassen können. Der folgende Wert ist ein pointObj, das die Bildkoordinaten des angeklickten Punktes darstellt. Falls Sie mit diesen Werten irgendwelche Berechnungen anstellen wollen, beachten Sie, dass der Ursprung der Grafik auf dem Bildschirm in der linken oberen Ecke ist.&lt;br /&gt;
&lt;br /&gt;
Breite und Höhe beziehen sich auf das Bild und sind Pixel-Werte. Der Extent (als rectObj) ist schließlich die Bounding Box der Karte in ihrem jeweiligen Koordinatensystem.&lt;br /&gt;
&lt;br /&gt;
Als letzten Wert könnte man übrigens noch ein weiteres rectObj angeben, dass den maximalen Extent angibt, der beim Zoomen nicht verlassen werden darf. Diesen Aufwand muß man aber nicht unbedingt treiben, da das Schlüsselwort =MAXSCALE=  in der Web-Sektion das gleiche leistet.&lt;br /&gt;
&lt;br /&gt;
Im Grunde machen alle Zoomfunktionen nichts anderes, als neue Extents für einen Kartenausschnitt festzulegen. Das bedeutet aber auch, dass Ihre Applikation durcheinander kommen kann, wenn sie beispielsweise gleichzeitig die Möglichkeit zum Zoomen und zum Ändern der Größe der Karte anbietet. Stellen Sie in Ihrem Code sicher, dass Sie in einem solchen Fall zuerst die Änderung des Ausschnitts vornehmen (z.B. Zoomen) und erst danach die Werte für die Kartengeometrie setzen (zum Beispiel Höhe und Breite der Karte).&lt;br /&gt;
&lt;br /&gt;
Das ''Zoomen auf ein Rechteck''  gestaltet sich ähnlich. Über normale Anwendungen im Webbrowser lassen sich zwei angeklickte Punkte nicht übertragen. Diese Funktion kommt also dann zum Tragen, wenn man mit JavaScript oder wie auch immer ein Rechteck aufziehen und entsprechende Werte übergeben kann.&lt;br /&gt;
&lt;br /&gt;
Der aufmerksame Leser kommt natürlich auch auf die Idee, diese Funktion zu benutzen, wenn er auf ein bestimmtes Feature zoomen möchte. Man bestimme dann die Extents des betreffendes Shapes (das geht auch mit MapScript, siehe weiter unten) und zoomt eben auf diese.&lt;br /&gt;
&lt;br /&gt;
Dummerweise geht das nur, wenn man die ''Pixel'' -Koordinaten des Rechtecks kennt, denn die Funktion =zoomRectangle=  wird folgendermaßen genutzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
 &amp;lt;math&amp;gt;map -&amp;gt; zoomRectangle (&amp;lt;/math&amp;gt;pixext, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;math&amp;gt;extent);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ist wieder ein rectObj; er gibt die Pixelkoordinaten des Rechtecks an, auf die gezoomt werden soll. Die Breite und die Höhe sind ebenfalls Pixelangaben im Bild. Die Extents schließlich sind wieder ein RectObj, das diesmal die Bounding Box der Karte im Bild im entsprechenden Koordinatensystem angibt.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie einfach auf bestimmte Extents zoomen wollen, ohne vorher in Besitz von Pixelkoordinaten und so weiter zu sein, dann können Sie einfach das Mapfile laden und diese neuen Extents setzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
 &amp;lt;math&amp;gt;map -&amp;gt; setExtent (&amp;lt;/math&amp;gt;minx, &amp;lt;math&amp;gt;miny, &amp;lt;/math&amp;gt;maxx, &amp;lt;math&amp;gt;maxy);&lt;br /&gt;
 &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warum diese Methode vier einzelne Koordinaten erwartet und kein RectObj, können wir leider nicht erklären.&lt;br /&gt;
&lt;br /&gt;
Die letzte Zoommethode schließlich ist =zoomScale= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
 &amp;lt;math&amp;gt;map -&amp;gt; zoomScale (100000, &amp;lt;/math&amp;gt;imgxy, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;/math&amp;gt;extent);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Wert ist ein SCALE, wie er bereits auf Seite~\pageref{text:mapfile:scale} besprochen worden ist. Beachten Sie bitte, dass so ein Maßstab nicht viel mit dem Maßstab auf einer gedruckten Karte zu tun hat.&lt;br /&gt;
&lt;br /&gt;
Die restlichen Parameter sind wieder die Pixelkoordinaten des Mausklicks, Höhe und Breite des Bildes in Pixeln sowie die Extents des Kartenausschnitts. Auch bei dieser Funktion läßt sich als letzter Parameter wieder als rectObj ein Ausschnitt angeben, aus dem nicht herausgezoomt werden darf.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Eigenschaften und Methoden}&lt;br /&gt;
&lt;br /&gt;
Die restlichen Eigenschaften des mapObj-Objektes dienen dazu, Informationen beziehungsweise Referenzen auf andere Objekte aus dem Mapfile zu ziehen; aber auch, Queries auszuführen. Mehr zu Queries in PHP erfahren Sie weiter unten in dem Abschnitt über Layer. Sie finden die Queries dort (und nicht hier im mapObj, wo sie ausgeführt werden), da die Resultate auf Layer-Ebene eingeholt werden.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Methoden und Eigenschaften, die mapObj bietet, sind im Anhang ab Seite~\pageref{ref:phpms:mapobj} aufgelistet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlerbehandlung==(3)&lt;br /&gt;
&lt;br /&gt;
Jetzt da Sie ein Gefühl dafür haben, wie man Objekte in PHP MapScript anspricht, sollen Sie etwas über die Wege der Fehlerbehandling erfahren, die mit MapServer 4.0 dazugekommen ist.&lt;br /&gt;
&lt;br /&gt;
Bisher sind Fehler einfach aufgetreten und haben meist den weiteren Ablauf des Skripts abgebrochen. Das kann eventuell nicht erwünscht sein; so wäre es zum Beispiel vorstellbar, dass eine Datenbank, die räumliche Daten für einen Layer Ihrer Applikation vorhält, nicht erreichbar ist. Anstatt nun einfach mit einem Fehler abzubrechen, wäre es natürlich angenehmer, wenn man beim Auftreten eines Fehlers dessen Ursache prüfen könnte, nd dann über das weitere Vorgehen entscheiden könnte.&lt;br /&gt;
&lt;br /&gt;
Dieses Vorgehen wird in MapScript 4.0 mit dem neuen Objekt =errorObj=  umgesetzt. Dabei werden Fehler bei ihrem Auftreten in eine interne Liste eingefügt. Aus dieser Liste können sie sodann zu einem Zeitpunkt nach Wahl des Programmierers entnommen und verarbeitet werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns das Beispiel von der offiziellen MapServer-Dokumentationsseite an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ms_resetErrorList ();&lt;br /&gt;
 &amp;lt;math&amp;gt;img = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
 &amp;lt;math&amp;gt;error = ms_getErrorObj ();&lt;br /&gt;
 while (&amp;lt;math&amp;gt;error &amp;amp;&amp;amp; &amp;lt;/math&amp;gt;error -&amp;gt; code != MS_NOERR) {&lt;br /&gt;
   printf (&amp;quot;Error in &lt;br /&gt;
            &amp;lt;math&amp;gt;error -&amp;gt; routine, &amp;lt;/math&amp;gt;error -&amp;gt; message);&lt;br /&gt;
            &amp;lt;math&amp;gt;error = &amp;lt;/math&amp;gt;error -&amp;gt; next ();&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst sollten Sie zu Beginn jedes Skriptes die Fehlerliste zurücksetzen; das passiert hier in der ersten Zeile.&lt;br /&gt;
&lt;br /&gt;
Danach holt man sich das globale Fehlerobjekt, über welches dann iteriert wird. Für jeden erzeugten Fehler wird dessen Eigenschaft =code=  abgefragt. Dieser Code ist eine aus einer Liste von Fehlerkonstanten. Falls es sich tatsächlich um einen Fehler handelt -- auch keine Fehler ist ein Fehler, allerdings einer vom Typ =MS_NOERR=  wird eine entsprechende Fehlermeldung ausgegeben. Danach wird zum nächsten unbearbeiteten Fehler in der Liste gesprungen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie nach der Abfrage des nächsten Fehlers keine Möglichkeit mehr haben, zu bereits abgearbeiteten Fehlern zurückzukehren.&lt;br /&gt;
&lt;br /&gt;
Sie finden alle Details zu =errorObj=  in der Referenz ab Seite~\pageref{ref:phpms:errorobj}. Die möglichen Fehlercodes sind außerdem Bestandteil von Tabelle~\ref{tab:ref:mapscript:const}, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt.&lt;br /&gt;
&lt;br /&gt;
==Die layerObj-Klasse==\index{Mapscript!layerObj}\index{layerObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt läßt Sie auf alle Bestandteile einer Layer-Sektion im Mapfile zugreifen.&lt;br /&gt;
&lt;br /&gt;
Dafür müssen Sie natürlich erst einmal wissen, welche Layer sich in einem gegebenen Mapfile befinden. Natürlich könnte man einfach alle Namen in seinem Script hartkodieren. Allerdings kommt man dann schnell in Bedrängnis, wenn sich am Mapfile etwas ändert. Außerdem läßt sich auf diese Weise keine Software schreiben, die sich mit beliebigen Mapfiles auseinandersetzt.&lt;br /&gt;
&lt;br /&gt;
Zuerst einmal können alle Layer in einem Mapfile durch einen Index angesprochen werden, der ihrer Position im Mapfile entspricht. Der erste Layer erhält dabei den Index =0= , der zweite den Index =1=  und so weiter\footnote{Informatiker beginnen immer bei Null mit dem Zählen, nicht bei Eins. Das liegt daran, dass sie sich bei Listen und so weiter nicht dafür interessieren, welche Position ein Element absolut besitzt, sondern welchen Abstand vom Beginn der Liste. Und der ist für das erste Element Null, und so weiter.}. Mit einer Schleife, die über die Anzahl der Layer läuft, kann man also beispielsweise folgendes machen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;num = &amp;lt;/math&amp;gt;map -&amp;gt; numlayers;&lt;br /&gt;
 for (&amp;lt;math&amp;gt;i = 0; &amp;lt;/math&amp;gt;i &amp;lt; numlayers; &amp;lt;/math&amp;gt;i++) {&lt;br /&gt;
   &amp;lt;math&amp;gt;layer = &amp;lt;/math&amp;gt;map -&amp;gt; getlayer (&amp;lt;math&amp;gt;i);&lt;br /&gt;
   ... jetzt passieren Dinge mit &amp;lt;/math&amp;gt;layer ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann die Layer aber auch über Ihren Namen ansprechen. Dabei holt man sich zuerst alle Layer-Namen via =getAllLayerNames()=  aus dem mapObj (man erhält ein Array aller Namen zurück), und spricht dann die Layer einzeln mit =getLayerByName()=  an.&lt;br /&gt;
&lt;br /&gt;
Die häufigste Aktion mit einem Layer ist, Queries auszuführen, beziehungsweise danach Query-Ergebnisse aus ihm herauszuholen.&lt;br /&gt;
&lt;br /&gt;
===Queries auf Layer===&lt;br /&gt;
&lt;br /&gt;
Queries liefern seit Version~{3.5} des MapServers keine Objekte vom Type resultObj mehr direkt zurück. Vielmehr werden die Ergebnisse von Queries nun in den Layer-Objekte festgehalten.&lt;br /&gt;
&lt;br /&gt;
Damit Anfragen auf einen Layer gemacht werden können, muß dieser im Mapfile einen =TEMPLATE= -Eintrag besitzen. Dieser Eintrag kann durchaus leer sein. Alternativ zur Angabe auf Layer-Ebene kann =TEMPLATE=  auch nur in einigen (oder allen) =CLASS= es des Mapfiles stehen. Die Queries werden dann nur auf Mitglieder dieser Klasse angewendet.&lt;br /&gt;
&lt;br /&gt;
Am häufigsten werden Queries auf einem mapObj ausgeführt; alle Query-Funktionen lassen sich jedoch auch auf einzelne Layer anwenden. Werden Queries auf mapObj-Objekte angewendet, werden einfach alle in Frage kommenden Layer der Reihe nach mit  der entsprechenden Funktion bedacht.&lt;br /&gt;
&lt;br /&gt;
Queries können auf drei verschiedene Weisen ausgeführt werden: an bestimmten Punkten, mit Hilfe eines Rechtecks und, ganz neu, anhand beliebiger Shapes. Doch wir beginnen mit den Punkt-Queries.&lt;br /&gt;
&lt;br /&gt;
Betrachten Sie folgendes Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
 &amp;lt;/math&amp;gt;punkt -&amp;gt; setXY (300000, 500000);&lt;br /&gt;
 &amp;lt;math&amp;gt;layer -&amp;gt; queryByPoint (&amp;lt;/math&amp;gt;punkt, MS_SINGLE, -1);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird zuerst ein Punkt-Objekt aus den Koordinaten gebaut, die abgefragt werden sollen. Für gewöhnlich kommen diese Koordinaten durch einen Mausklick auf ein Bild in einem Formular zustande. Beachten Sie bitte, dass dieser Punkt im =Koordinatensystem der Karte=  vorliegen muß; die Pixelwerte eines Mausklicks auf eine Karte müssen Sie also zuerst in passende Werte umrechnen.&lt;br /&gt;
&lt;br /&gt;
Danach wird auf dem gewünschten Layer eine Query durchgeführt. Dazu wird der Punkt übergeben, die Art der Anfrage (hier soll nur ein einzelnes Ergebnis erzeugt werden; mit =MS_MULTIPLE=  wären mehrere Ergebnisse möglich), und schließlich ein Puffer. Dieser Puffer ist ein Radius um den Abfragepunkt herum, in den Einheiten der Karte. Ein negativer Wert führt dazu, dass der im Mapfile gesetzte Wert verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Bevor man sich auf eventuelle Resultate stürzt, sollte man prüfen, ob es überhaupt Resultate gab -- die Anfrage kann schließlich auch ins Leere gegangen sein. Dazu prüft man den Rückgabewert der Funktion. Ist dieser =MS_SUCCESS= , so ist alles in Ordnung und man kann fortfahren. Trifft man auf =MS_FAILURE= , so gab es keine Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
Etwas problematisch ist, dass alle Query-Funktionen auch Fehlernachrichten produzieren, wann immer es keine Resultate gab. Dieses Verhalten läßt sich für einzelne Funktionen jedoch mit einem vorangestellten =@=  abstellen. Ein korrekterer Aufruf der obigen Funktion wäre also:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if ((&amp;lt;math&amp;gt;layer -&amp;gt; @queryByPoint (&amp;lt;/math&amp;gt;punkt, MS_SINGLE, -1))&lt;br /&gt;
                                           == MS_SUCCESS) {&lt;br /&gt;
   ... es gab Ergebnisse ...&lt;br /&gt;
 } else {&lt;br /&gt;
   ... Fehlerbehandlung ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt können wir uns endlich mit dem Ergebnis des Mausklicks auseinandersetzen. Oder besser: mit den Ergebnissen, denn es können ja mehre sein. Mit =getnumresult()=  bringen wir die Anzahl der Resultate eines Layers in Erfahrung; haben wir nur ein Resultat, ist das nicht nötig. Dieses eine Resultat hat immer den Index =0= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;resultat = &amp;lt;/math&amp;gt;layer -&amp;gt; getResult (0);&lt;br /&gt;
 &amp;lt;math&amp;gt;si = &amp;lt;/math&amp;gt;resultat -&amp;gt; shapeindex;&lt;br /&gt;
 &amp;lt;math&amp;gt;ti = &amp;lt;/math&amp;gt;resultat -&amp;gt; tileindex;&lt;br /&gt;
 &amp;lt;math&amp;gt;ti = &amp;lt;/math&amp;gt;resultat -&amp;gt; classindex;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat-Objekt besitzt also drei Eigenschaften: einen Shapeindex, der die Nummer des Shapes im Shapefile angibt, das dem Layer zugrunde liegt; einen Tileindex, der für gekachelte Shapefiles angibt, in welcher Kachel das Ergebnis aufgetreten ist; und schließlich einen Classindex, der die Class im Layer bezeichnet, für den das Ergebnis aufgetreten ist.&lt;br /&gt;
&lt;br /&gt;
Mit diesen Angaben können Sie dann verfahren, wie Sie es für richtig halten. Sie können zum Beispiel die Daten aus dem =.dbf= -File herausfischen, die dem Shape zugrunde liegen\footnote{Beachten Sie an dieser Stelle die eigenwillige Zählweise in =.dbf= -Dateien, die auch in PHP übernommen wurde: die Zeilen in einer solche Datei sind nicht bei 0 beginnend durchnummeriert, sondern bei 1}. Sie könnten beispielsweise auch auf das gesuchte Shape heranzoomen, indem Sie anhand des gefundenen Index die Bounding Box des Shapes aus dem Shapefile auslesen (siehe auch shapefileObj weiter unten) und diese Bounding Box als neue Extents für die Karte setzen.&lt;br /&gt;
&lt;br /&gt;
Von den einfachen Punkt-Queries kann man nun voranschreiten zu den Anfragen, die über ein Rechteck definiert sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;layer -&amp;gt; queryByRect (&amp;lt;/math&amp;gt;rechteck);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Rechteck ist dabei ein rectObj, wie es weiter unten im Text besprochen wird. Die restliche Vorgehensweise entspricht exakt demjenigen bei Punktabfragen.&lt;br /&gt;
&lt;br /&gt;
Hinweise: Rechtecke lassen sich in &amp;quot;`normalem&amp;quot;' HTML nicht erzeugen. Mit JavaScript oder dem ROSA-Applet sieht das schon wieder anders aus. Beachten Sie aber, dass insbesondere öffentliche Institutionen unter Umständen äußerst restriktive Bestimmungen haben, was den Einsatz von JavaScript, dynamischem HTML, Java und so weiter angeht. Auch sicherheitsbewußte Privatanwender haben JavaScript erst gar nicht aktiviert. Überdenken Sie den Einsatz dieser Technologien.&lt;br /&gt;
&lt;br /&gt;
Das gilt auch für die folgende Weise, Queries zu stellen, nämlich anhand eines Shapes, also eines beliebigen Polygons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;layer -&amp;gt; queryByShape (&amp;lt;/math&amp;gt;shape);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Art der Query entfaltet Ihren Nutzen weniger anhand von Punkten, die in einem Web-Interface ausgewählt werden können, als vielmehr beim Vergleich von Shapes mit Shapes aus einem anderen Shapefile: wenn Sie beispielsweise ein Shapefile mit Bundesländern haben und eines, indem ohne eine solche Referenzierung Angaben von Verkaufszahlen gespeichert sind, dann lassen sich durch den 'Verschnitt' beider Daten aussagekräftige Ergebnisse erzeugen.&lt;br /&gt;
&lt;br /&gt;
Wie man mit MapScript einzelne Shapes aus einem Shapefile extrahiert erfahren Sie weiter unten bei der Besprechung von shapefileObj. Ein schneller Weg involviert allerdings die Methode =getShape()= , die bereits auf der Ebene des Layers vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Eigenschaften und Methoden}&lt;br /&gt;
&lt;br /&gt;
Die weiteren Funktionen in layerObj dienen im wesentlichen dazu, Zugriff auf die einzelnen Werte eines Layers zu erhalten, beziehungsweise auf die weiteren Objekte darin bezug nehmen zu können, insbesondere auf die Classes im Layer.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Methoden und Eigenschaften, die layerObj bietet, sind im Anhang ab Seite~\ref{ref:phpms:layerobj} aufgelistet.&lt;br /&gt;
&lt;br /&gt;
==Die classObj-Klasse==\index{Mapscript!classObj}\index{classObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt entspricht einer Class innerhalb eines Layers. Mit einem classObj können Sie im wesentlichen Farben und Symbole für eine Class setzen -- insbesondere aber die Expressions für eine Class.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel, wie man das verwenden kann: Nehmen wir an, Sie haben einen Datenbestand, der Ihnen die Deutschland in lauter kleine Gebiete einteilt. In der dazu gehörigen ''.dbf'' -Datei haben Sie in einer Spalte für jedes Gebiet den prozentualen Anteil an Waldfläche gespeichert. Diese Spalte trägt den Namen =WALD= .&lt;br /&gt;
&lt;br /&gt;
In Ihrer Applikation haben Sie nun ein Eingabefeld, das es dem Benutzer ermöglicht, eine Anzahl von Grün-Abstufungen zu bestimmen, in die der Layer eingeteilt werden soll. Gibt der Benutzer beispielsweise =4=  ein, werden dem Layer vier Klassen hinzugefügt, die von grün bis weiß vier Farbstufen annehmen.&lt;br /&gt;
&lt;br /&gt;
Sie errechnen in der PHP-Seite dann die Unterteilung in vier Grünstufen und setzen vier verschiedene Classes.&lt;br /&gt;
&lt;br /&gt;
==Die imageObj-Klasse==\index{Mapscript!imageObj}\index{imageObj}&lt;br /&gt;
&lt;br /&gt;
Diese Objekte werden niemals 'von Hand' erzeugt, sondern immer nur durch den Aufruf von Methoden anderer MapScript-Objekte. Bei diesen Image-Objekten handelt es sich nicht um Bild-Dateien, sondern lediglich um die Bilddaten, die in einem Puffer im Speicher liegen und noch darauf warten, gespeichert zu werden.&lt;br /&gt;
&lt;br /&gt;
Alle =draw= -Methoden von mapObj erzeugen ein imageObj. Am häufigsten wird danach die Methode =saveWebImage()=  aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;image = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
 &amp;lt;math&amp;gt;url = &amp;lt;/math&amp;gt;image -&amp;gt; saveWebImage (MS_JPEG, 0, 0, 90);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter der Methode ist das gewünschte Bildformat, das meistens =MS_PNG=  sein wird, ab und zu =MS_JPEG=  und nur, wenn es sich nicht vermeiden läßt, =MS_GIF= .&lt;br /&gt;
&lt;br /&gt;
Die beiden folgenden Parameter legen eine Transparenz der Hintergrundfarbe bzw. ein Interlacing für das Bild fest. Der letzte (optionale) Parameter legt für Bildformate, die eine Kompression zur Verfügung stellen, den Grad dieser Kompression fest. Werte zwischen 0 und 100 sind hier möglich.&lt;br /&gt;
&lt;br /&gt;
Eine vollständige Aufzählung aller Methoden dieses Objektes finden Sie im Anhang ab Seite~\pageref{ref:phpms:imageobj}.&lt;br /&gt;
&lt;br /&gt;
==Die labelObj-Klasse==\index{Mapscript!labelObj}\index{labelObj}&lt;br /&gt;
&lt;br /&gt;
Labels befinden sich innerhalb von classObj-Objekten. Diese Klasse kennt erstaunlicherweise keine einzige Methode außer =set()= , dafür eine große Menge von Eigenschaften. In der Referenz finden Sie ab Seite~\pageref{ref:phpms:labelobj} eine ausführliche Aufzählung.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet übrigens auch, dass es keinen Konstruktor für diese Klasse gibt und demnach keine Möglichkeit, ein labelObj 'von Hand' zu erstellen.&lt;br /&gt;
&lt;br /&gt;
==Die webObj-Klasse==\index{Mapscript!webObj}\index{webObj}&lt;br /&gt;
&lt;br /&gt;
Ebenso wie beim labelObj gibt es auch für diese Klasse keinen Konstruktor und keine weiteren Methoden neben der =set()= -Methode. In der Referenz im Anhang finden Sie ab Seite~\pageref{ref:phpms:webobj} eine Liste aller Eigenschaften dieser Klasse.&lt;br /&gt;
&lt;br /&gt;
webObj-Objekte finden Sie immer als Bestandteil eines mapObj.&lt;br /&gt;
&lt;br /&gt;
==Die referenceMapObj-Klasse==\index{Mapscript!referenceMapObj}\index{referenceMapObj}&lt;br /&gt;
&lt;br /&gt;
Auch Objekte dieser Klasse kommen nur innerhalb eines mapObj vor, es gibt keinen Konstruktor und keine Methode außerhalb von =set()= .&lt;br /&gt;
&lt;br /&gt;
In der Referenz ab Seite~\pageref{ref:phpms:referencemapobj} finden Sie eine Liste aller Eigenschaften dieser Klasse.&lt;br /&gt;
&lt;br /&gt;
==Die colorObj-Klasse==\index{Mapscript!colorObj}\index{colorObj}&lt;br /&gt;
&lt;br /&gt;
Jede Karte verfügt über eine bestimmte Farbpalette. Diese Palette wird beim Generieren der Karte erstellt.&lt;br /&gt;
&lt;br /&gt;
Neue Farben lassen sich der Palette hinzufügen, indem man Objekte der Klasse colorObj erzeugt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;weiss = ms_newColorObj ();&lt;br /&gt;
 &amp;lt;/math&amp;gt;weiss -&amp;gt; setRGB (255, 255, 255);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Farbe kann dann an den Stellen, wo es möglich und nötig ist, verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==Die pointObj-Klasse==\index{Mapscript!pointObj}\index{pointObj}&lt;br /&gt;
&lt;br /&gt;
Punkte werden an diversen Stellen in MapScript für verschiedene Dinge benötigt. Wann immer eine Funktion die zwei Koordinaten eines Punktes übergeben bekommt, wird ein pointObj verlangt. Sehen Sie sich beispielsweise die Verwendung von =queryByPoint=  im Abschnitt über das Objekt =layerObj=  an.&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt besitzt aber noch einige andere Methoden in MapScript. Insbesondere kann man damit die Abstände von Punkten zu anderen Punkten, zu Linien und zu Polygonen bestimmen; außerdem lassen sich einzelne Punkte mithilfe von Objekten der Klasse projectionObj projizieren. Des weiteren kann man einzelne Punkte aus Linien-Objekten extrahieren (siehe lineObj).&lt;br /&gt;
&lt;br /&gt;
pointObj gehört zu den Klassen, deren Speicher nach Gebrauch explizit freigegeben werden muß (siehe Seite~\pageref{text:mapscript:memory}).&lt;br /&gt;
&lt;br /&gt;
Die Referenz zu allen Methoden von pointObj finden Sie auf Seite~\pageref{ref:phpms:pointobj}.&lt;br /&gt;
&lt;br /&gt;
==Die lineObj-Klasse==\index{Mapscript!lineObj}\index{lineObj}&lt;br /&gt;
&lt;br /&gt;
Linien lassen sich entweder von Hand konstruieren (indem man der Reihe nach einzelne Punkte hinzufügt), oder aber aus Shapes der Klasse shapeObj extrahieren. Außerdem lassen sich Linien natürlich ebenfalls projizieren.&lt;br /&gt;
&lt;br /&gt;
lineObj gehört zu den Klassen, deren Speicher nach Gebrauch explizit freigegeben werden muß (siehe Seite~\pageref{text:mapscript:memory}).&lt;br /&gt;
&lt;br /&gt;
Die Referenz zu allen Methoden von lineObj finden Sie auf Seite~\pageref{ref:phpms:lineobj}.&lt;br /&gt;
&lt;br /&gt;
==Die projectionObj-Klasse==\index{Mapscript!projectionObj}\index{projectionObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt beschreibt einen Projektions-Abschnitt in einem Mapfile. Aber es kann auch jenseits von Mapfiles verwendet werden, um einzelne Punktkoordinaten umzuprojizieren.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel projiziert einen einzelnen Punkt von einer Längen-/Breitenangabe in einen Punkt im UTM 32-System:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;projin = ms_newProjectionObj (&amp;quot;proj=latlong&amp;quot;);&lt;br /&gt;
 &amp;lt;/math&amp;gt;projout = ms_newProjectionObj (&amp;quot;proj=utm,zone=32,ellps=WGS84,&lt;br /&gt;
                                  datum=WGS84,no_defs&amp;quot;);&lt;br /&gt;
 &amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
 &amp;lt;/math&amp;gt;punkt -&amp;gt; setXY (32.0, 51.0);&lt;br /&gt;
 &amp;lt;math&amp;gt;punkt = &amp;lt;/math&amp;gt;punkt -&amp;gt; project ();&lt;br /&gt;
 printf (&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die genauen Parameter, die Sie für die von Ihnen gewünschte Projektion verwenden müssen, finden Sie in der Dokumentation der Projektionsbibliothek proj.4.&lt;br /&gt;
&lt;br /&gt;
==Die shapefileObj-Klasse==\index{Mapscript!shapefileObj}\index{shapefileObj}&lt;br /&gt;
&lt;br /&gt;
Diese Klasse dient dazu, Shapefiles direkt manipulieren zu können. Sie können ein Shapefile als Objekt öffnen, einzelne Shapes referenzieren, die Eigenschaften des Shapefiles auslesen und sogar neue Shapes an das Shapefile anhängen und ganz neue Shapfiles erschaffen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie kein mapObj erzeugen müssen, um Shapefiles auf diese Weise zu bearbeiten. Das shapefileObj ist unabhängig von den MapServer-verwandten Klassen in MapScript, kann aber natürlich mit diesen zusammen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Referenz für alle Eigenschaften und Methoden von shapefileObj finden Sie ab Seite~\ref{ref:phpms:shapefileobj}.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel gibt eine simple Statistik über alle Shapefiles aus, die es im aktuellen Verzeichnis finden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 foreach (glob (&amp;quot;*.shp&amp;quot;) as &amp;lt;math&amp;gt;shpfname) {&lt;br /&gt;
   &amp;lt;math&amp;gt;shpf = ms_newShapefileObj (&amp;lt;/math&amp;gt;shpfname, -1);&lt;br /&gt;
   &amp;lt;math&amp;gt;noshapes = &amp;lt;/math&amp;gt;shpf -&amp;gt; numshapes;&lt;br /&gt;
   &amp;lt;math&amp;gt;shpftype = &amp;lt;/math&amp;gt;shpf -&amp;gt; type;&lt;br /&gt;
   &amp;lt;math&amp;gt;bounds = &amp;lt;/math&amp;gt;shpf -&amp;gt; bounds;&lt;br /&gt;
   printf (&amp;quot;Anzahl der Shapes: &lt;br /&gt;
           &amp;quot;Typ des Shapefiles: &lt;br /&gt;
           &amp;quot;Extents: &lt;br /&gt;
           &amp;lt;math&amp;gt;noshapes, &amp;lt;/math&amp;gt;shpftype,&lt;br /&gt;
           &amp;lt;math&amp;gt;bounds -&amp;gt; minx, &amp;lt;/math&amp;gt;bounds -&amp;gt; miny,&lt;br /&gt;
           &amp;lt;math&amp;gt;bounds -&amp;gt; maxx, &amp;lt;/math&amp;gt;bounds -&amp;gt; maxy);&lt;br /&gt;
   &amp;lt;/math&amp;gt;shpf -&amp;gt; free ();&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Struktur von PHP MapScript-Seiten==&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit PHP MapScript das Verhalten einer 'normalen' MapServer-Applikation nachbilden möchten, kann Ihnen das folgende Schema einige Anhaltspunkte geben, wie beim Aufbau einer solchen Applikation vorgegangen werden kann.&lt;br /&gt;
&lt;br /&gt;
Weitere Optionen für Ihre Applikation müssen an sinnvollen Stellen in das Gerüst eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung ist natürlich kein in Stein gemeißeltes Gesetz, sondern kann von Fall zu Fall abgeändert werden. Es bietet aber eine gute Orientierungshilfe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#Prüfen der übergebenen Parameter auf sinnvolle Werte&lt;br /&gt;
#Laden des Mapfiles&lt;br /&gt;
#Fallunterscheidung nach gewünschtem Modus:&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	##Simples Browsen (Pan) der Karte:&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Koordinaten des Mausklicks  		##&lt;br /&gt;
*Zoomen auf den Punkt mit einer Zoomtiefe von 1  		&lt;br /&gt;
	##Zoomen auf/um den betreffenden Punkt&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Koordinaten des Mausklicks  		##&lt;br /&gt;
*Zoomen auf den Punkt mit dem übergebenen Zoomfaktor  		&lt;br /&gt;
	##Zoomen auf das angeklickte Shape&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Shapenummer mittels queryByPoint  		##&lt;br /&gt;
*Öffnen des entsprechenden Shapefiles und Ermitteln der Extents des angeklickten Shapes  		##&lt;br /&gt;
*Zoomen auf das Shape mittels zoomByRect  		&lt;br /&gt;
	##Query auf den geklickten Punkt&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Kartenkoordinaten des angeklickten Punktes (oder mehrerer Punkte, falls es ein queryByRect ist)  		##&lt;br /&gt;
*Ausführen der Query  		##&lt;br /&gt;
*Auslesen des Ergebnis' (oder der Ergebnisse) aus einem oder mehreren Layer-Objekten  		##&lt;br /&gt;
*Präsentation der Ergebnisse  		&lt;br /&gt;
	&lt;br /&gt;
#Rendern der Karte und Abspeichern in einer Datei&lt;br /&gt;
#Eintragen des URL des fertigen Bildes in den entsprechenden HTML-Tag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Speichern von Map-Objekten in PHP-Sessions==&lt;br /&gt;
&lt;br /&gt;
Leider können Objekte aus PHP-MapScript (insbesondere ein mapObj) nicht in Sessions gespeichert werden. Der Grund dafür ist, dass die Objekte in PHP-MapScript keine 'reinen' PHP-Objekte sind, sondern lediglich als Wrapper um die C-Daten\-struk\-turen des MapServer-Quellcodes angelegt sind. Das führt dazu, dass beim Speichern in einer Sitzungsvariablen lediglich der Wrapper gespeichert wird, nicht aber das darunter liegende Objekt.&lt;br /&gt;
&lt;br /&gt;
Man muß also entweder (um beim Beispiel eines mapObj zu beiben) die ''vorgenommenen Änderungen''  auf eine genehme Art und Weise speichern und mitschleifen, um diese dann jedesmal auf ein neu erstelltes mapObj anzuwenden; oder man speichert die fertige Karte als Datei im System ab und speichert den Dateinamen der Karte in der Sitzungsvariablen.&lt;br /&gt;
&lt;br /&gt;
==Speicherverwaltung mit MapScript==(4)&lt;br /&gt;
&lt;br /&gt;
Die Speicherverwaltung aller MapScript-Objekte, die im Zusammenhang mit dem Mapfile stehen, geschieht automatisch. Sie müssen also nicht für jedes Objekt Speicher anfordern und wieder freigeben.&lt;br /&gt;
&lt;br /&gt;
Etwas anders verhält es sich bei Objekten zu Shapefiles und allen geometrischen Objekten wie Punkten, Linien und so weiter. Das Anfordern von Speicher entfällt zwar. Allerdings sollten alle Objekte dieser am Ende (also nachdem man Gebrauch von ihnen gemacht hat und sie nicht mehr benötigt) explizit zerstört und alle verwendeten Resourcen freigegeben werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; free ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwar wird jeder Speicher, der innerhalb eines PHP-Skriptes benutzt wird, nach dem Abarbeiten der Seite automatisch wieder freigegeben. Allerdings kann bei beim exzessiven Gebrauch von Objekten innerhalb einer Seite vielleicht in Speicherschwierigkeiten kommen.&lt;br /&gt;
&lt;br /&gt;
Außerdem können Sie in Ihrem Programm zwar keine Probleme mit dem Speicher haben. Denken Sie aber immer daran, dass Kollegen, Freunde, Mitarbeiter und so weiter später vielleicht auf die Idee kommen können, das Programm abzuändern und zu erweitern. Wenn Sie von vornherein vernünftig mit dem Speicher umgegangen sind, so sind Sie auf der sicheren Seite. Es zeugt darüber hinaus von einem sauberen Programmierstil.&lt;br /&gt;
&lt;br /&gt;
=Weitere Sprachen=&lt;br /&gt;
&lt;br /&gt;
MapScript kann mit verschiedenen Sprachen genutzt werden. Neben PHP sind die populärsten Perl, Java und Python.&lt;br /&gt;
&lt;br /&gt;
Die MapServer-Entwickler bedienen sich bei diesen Sprachen des Interface-Generators SWIG~[[http:website:swig]]. Die Verwendung von SWIG und die Erstellung von MapScript-Modulen für andere Programmiersprachen wird im Anhang besprochen.&lt;br /&gt;
&lt;br /&gt;
==Perl==&lt;br /&gt;
&lt;br /&gt;
Zu Perl gibt es unglaublich viel Literatur. Nichts falsch machen kann man wohl mit~[[wall:1996:perl5]], dem berühmten Camel Book. Es ist auch auf deutsch erschienen.&lt;br /&gt;
&lt;br /&gt;
==Java==&lt;br /&gt;
&lt;br /&gt;
Java ist eine Sprache, aus der ein unglaublicher Hype hervorgegangen ist. Die Literatur, die sich mit Java auseinandersetzt, ist dermaßen umfangreich, dass Sie sich von dem Buchhändler Ihres Vertrauens beraten lassen sollten.&lt;br /&gt;
&lt;br /&gt;
==Python==&lt;br /&gt;
&lt;br /&gt;
Python hat sich einen Namen als einfache, strukturierte und schnell zu lernende Programmiersprache gemacht. Wer des Englischen mächtig ist, ist mit der Lektüre von~[[lutz:1999:python]] recht gut beraten; das Buch ist auch auf deutsch erschienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Java-Applets}\index{Applets}(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Mapplet=\index{Mapplet}(2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=ROSA=(3)\index{ROSA}&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_6&amp;diff=34431</id>
		<title>HBUMNMapServer ger Capter 6</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_6&amp;diff=34431"/>
		<updated>2009-01-23T10:14:20Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Setzen von Objekt-Eigenschaften */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= MapScript =&lt;br /&gt;
(1)\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
Bisher haben Sie den MapServer als Applikation kennengelernt, die in einem Webserver wie zum Beispiel Apache arbeitet, und direkt über Parameter des URL aufgerufen und in ihrem Verhalten beeinflußt werden kann.&lt;br /&gt;
&lt;br /&gt;
Man kann sich aber natürlich auch vorstellen, die Funktionen von MapServer -- das Lesen von Mapfiles, das Rendern der Karten und so weiter -- auch aus eigenen Programmen nutzen zu wollen, natürlich auch solchen, die nicht in einem Webserver laufen sollen. Dazu müßte man diese Funktionen separat zur Verfügung stellen, beispielsweise in einer eigenen Bibliothek, auf die dann aus anderen Programmiersprachen zugegriffen werden kann. Diese Bibliothek existiert bereits und trägt den Namen MapScript.&lt;br /&gt;
&lt;br /&gt;
Zu den Sprachen wie Java, Python, Perl und einigen anderen, die mit MapScript benutzt werden können, gesellt sich auch PHP. PHP MapScript soll im Folgenden als Anknüpfungspunkt für die Erklärung von MapScript dienen -- die genaue Terminologie für einzelne Programmiersprachen entnehmen Sie bitte der jeweilgen Dokumentation der Sprache bzw. den Beispielen, die dem MapServer-Quellcode beiliegen.&lt;br /&gt;
&lt;br /&gt;
=PHP MapScript=(2)\index{PHP MapScript}\index{MapScript!PHP}&lt;br /&gt;
&lt;br /&gt;
Ich erspare dem Leser die an dieser Stelle üblichen Hymnen auf PHP\footnote{Beziehungsweise die üblichen Flames. Die Sprache ist definitiv nichts für Puristen oder Entwickler mit eng gesteckten Vorgaben, was den Resourcenverbrauch angeht.} und seine Flexibilität als Sprache für Webanwendungen. Es ist in der Tat sehr weit verbreitet. Das ist (neben der besonderen Pflege, die gerade diese Sprachanbindung erfährt) auch der Grund, warum wir an dieser Stelle detailliert auf PHP MapScript eingehen, und nicht beispielsweise auf Perl.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle gehen wir nicht darauf ein, wie Sie PHP installieren, oder wie Sie Ihren Webserver korrekt für den Einsatz von PHP konfigurieren. Wie man das tut, erfahren Sie in der Dokumentation von PHP bzw. Ihres Webservers. Die Installation von PHP MapScript wird im Anhang dieses Handbuches abgehandelt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass PHP MapScript im Moment zwingend voraussetzt, dass Sie PHP ''nicht''  als Modul laden, sondern als CGI-Programm einsetzen. Es kann ansonsten zu nicht vorhersehbaren Komplikationen kommen.&lt;br /&gt;
&lt;br /&gt;
Als erstes deutschsprachiges Einsteigerbuch zu PHP eignet sich beispielsweise~[[theis:2000:php]]; allerdings gibt es eine solche Unzahl an Büchern über diese Sprache, dass eine persönliche Auswahl im Buchladen erfolgen sollte. Die Website zur PHP [[http:website:php]] stellt ausführliche Dokumentation bereits, die interessanterweise auch vollständig ins deutsche übersetzt ist.&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist es eine gute Idee, sich mit der FAQ von =de.comp.lang.php= ~[[faq:dclp]]  auseinanderzusetzen, der deutschsprachigen Newsgroup zu PHP, die in einem eigenen Kapitel auch auf Sicherheitsbelange eingeht.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{mapscript-hyk}{Ein Beispiel für eine PHP MapScript Anwendung sind die Hydrogeologischen Karten Brandenburg}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
==Laden des Moduls==&lt;br /&gt;
&lt;br /&gt;
Um die MapScript-Funktionen in einer PHP-Seite verwenden zu können, muss das Modul dafür geladen werden. Das geschieht ganz einfach durch ''dl'' :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 dl (&amp;quot;php_mapscript.so&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies sollte die erste Zeile sein, die Sie in jede Seite einfügen, die MapScript-Funktionen benutzt. Sollten Sie sich unter Windows befinden, ändert sich diese Zeile leicht in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 dl (&amp;quot;php_mapscript.dll&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine portable Anwendung schreiben sollen, ist es demnach angebracht, gleich zu Beginn des Skripts auf das verwendete Betriebssystem zu prüfen und dann die korrekte Datei zu laden.&lt;br /&gt;
&lt;br /&gt;
==Setzen von Objekt-Eigenschaften==&lt;br /&gt;
&lt;br /&gt;
Bevor Sie auch nur eine einzige Klasse aus MapScript kennenlernen, möchte ich zeigen, wie man die Eigenschaften von Objekten setzt, da diese Methode für alle Objekte (die sie unterstützen) gleich ist.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;layer -&amp;gt; set (&amp;quot;name&amp;quot;, &amp;quot;gruenflaechen&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit diesem Aufruf wird der Name eines Layer-Objektes auf =gruenflaechen=  gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der 'korrekte' objektorientierte Ansatz wäre natürlich gewesen, dafür eine eigene Routine =setName()=  zu implementieren. Da einige Klassen in MapScript jedoch über eine ziemlich große Anzahl an Eigenschaften verfügen, hat man sich auf diese Methode beschränkt.&lt;br /&gt;
&lt;br /&gt;
Das Setzen von Eigenschaften auf diese Weise funktioniert nur für Eigenschaften, die nicht =read-only=  sind. Nicht jedes Objekt implementiert zudem die =set()= -Methode. In der Referenz im Anhang dieses Handbuchs sehen Sie, welche Klasse eine solche Methode zur Verfügung stellt.&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus haben einige Klassen für einige Eigenschaften doch noch eigene Methoden implementiert. Studieren Sie die Referenz im Anhang, um herauszufinden, für welche Klassen und Eigenschaften das gilt.&lt;br /&gt;
&lt;br /&gt;
==Formulareingaben in PHP verarbeiten==&lt;br /&gt;
&lt;br /&gt;
In älteren PHP-Versionen war es kein Problem, URL-Parameter einfach als Variable in ein PHP-Skript zu übernehmen. Wenn ein Aufruf also etwa so aussah:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
.../skript.php?name=Calli&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann konnte man ohne Probleme das folgende in sein Skript schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
echo &amp;lt;/math&amp;gt;name;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das produzierte dann die Ausgabe =Calli= .&lt;br /&gt;
&lt;br /&gt;
In neueren Fassungen von PHP\footnote{Und aufgrund der bekannt gewordenen Sicherheitslücken möchte man eine alte Version nicht benutzen. Verwenden Sie nichts unter 4.3.3!} geht das so nicht mehr. Weil es durch diverse Tricksereien möglich war, globale PHP-Variablen von außen zu überschreiben, und weil man die Programmierer zwingen wollte, sich mit den Werten in ihren Variablen genauer zu befassen, muß man sich jeden Wert nun explizit aus einem Array holen, das den Namen =\&amp;lt;math&amp;gt;_GET[]=  trägt.&lt;br /&gt;
&lt;br /&gt;
Für unser obiges Beispiel benötigen Sie dann also folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;dername = &amp;lt;/math&amp;gt;_GET ['name'];&lt;br /&gt;
echo &amp;lt;/math&amp;gt;dername;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manchmal werden durch eine Eingabemöglichkeit in einem HTML-Formular mehrere Werte übergeben. Ein Beispiel dafür ist ein angeklicktes Bild, wie es etwa unsere Karte ist -- ein Klick produziert natürlich eine X- und eine Y-Koordinate. PHP verhält sich an dieser Stelle etwas unerwartet. Betrachten wir das folgende Bild in einem HTML-Formular:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;image&amp;quot; name=&amp;quot;img&amp;quot; src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach einem Klick finden Sie im URL zwei Werte, namentlich =img.x=  und =img.y= . Diese beiden Variablen werden Sie aber im Array =\&amp;lt;math&amp;gt;_GET[]=  vergeblich suchen, denn für PHP werden die Punkte durch Unterstriche ersetzt. Sie müssen sich also =img_x=  und =img_y=  aus dem Array holen.&lt;br /&gt;
&lt;br /&gt;
Es ist übrigens immer angezeigt, den Wert jeder Variablen, die von außen belegt wird, eingehend auf seine Sinnhaftigkeit zu prüfen.&lt;br /&gt;
&lt;br /&gt;
==Die mapObj-Klasse==\index{Mapscript!mapObj}\index{mapObj}&lt;br /&gt;
&lt;br /&gt;
Als nächstes möchten wir betrachten, wie MapScript ein Mapfile behandelt. Betrachten Sie das erste Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;image = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;math&amp;gt;imageurl = &amp;lt;/math&amp;gt;image -&amp;gt; saveWebImage (MS_PNG, 1, 1, 0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der ersten Zeile wird ein =mapObj=  erzeugt, das auf ein bereits existentes Mapfile zugreift. Danach wird daraus ein =ImageObj=  erzeugt, es wird also die Karte gezeichnet. Dabei werden die gesetzten Werte für die Extents aus dem Mapfile übernommen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass dadurch noch keine fertige Bild''datei''  erzeugt wird. Die Karte existiert zu diesem Zeitpunkt nur als Puffer im Speicher.&lt;br /&gt;
&lt;br /&gt;
In einer Datei tatsächlich gespeichert wird das Bild in der letzten Zeile, in unserem Beispiel als Bild im PNG-Format. Die Rückgabe der Funktion ist der URL für den Webserver, unter der er das Bild ausliefern kann.&lt;br /&gt;
&lt;br /&gt;
Man kann daher weiter unten in der Seite folgendes HTML verwenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;lt;?php echo &amp;lt;math&amp;gt;imageurl; ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird der betreffende URL in den =&amp;lt;img&amp;gt;= -Tag eingefügt und an den Client ausgeliefert. Das Resultat ist natürlich ein zentriertes Bild der Karte im Webbrowser.&lt;br /&gt;
&lt;br /&gt;
Auf die gleiche Weise werden übrigens auch Legenden, Maßstäbe und Referenzkarten erzeugt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;img_legend = &amp;lt;/math&amp;gt;map -&amp;gt; drawLegend ();&lt;br /&gt;
&amp;lt;math&amp;gt;img_scalebar = &amp;lt;/math&amp;gt;map -&amp;gt; drawScaleBar ();&lt;br /&gt;
&amp;lt;math&amp;gt;img_refmap = &amp;lt;/math&amp;gt;map -&amp;gt; drawReferenceMap ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch diese Bildobjekte werden wieder über deren Methode =saveWebImage=  abgespeichert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Zoomen}&lt;br /&gt;
&lt;br /&gt;
Das Zoomen in eine Karte kann auf drei Weisen geschehen: Zoomen in Richtung eines Punktes, Zoomen auf ein Rechteck und Zoomen auf einen Punkt in einem bestimmten Maßstab.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den ersten Fall. Wir gehen davon aus, dass wir ein Bild in einem HTML-Formular eingebettet hatten, und dieses Bild wie gerade beschrieben per PHP Mapscript erzeugt hatten. Wurde das Bild angeklickt, werden die Pixelkoordinaten des Klicks über das Formular mit übergeben. Gehen wir von einem festen Zoomfaktor von 2 aus (diesen Wert legen wir für dieses Beispiel jetzt fest), können wir mit diesen Pixeln folgendes tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/file.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; zoomPoint (2, &amp;lt;/math&amp;gt;imgxy, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;math&amp;gt;extent);&lt;br /&gt;
&amp;lt;math&amp;gt;img = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird in seinem ursprünglichen Zustand geladen. Dann werden der Zoomfunktion die nötigen Parameter übergeben: zuerst der Zoomfaktor, den wir hier mit 2 festlegen, aber natürlich auch im Formular einstellen lassen können. Der folgende Wert ist ein pointObj, das die Bildkoordinaten des angeklickten Punktes darstellt. Falls Sie mit diesen Werten irgendwelche Berechnungen anstellen wollen, beachten Sie, dass der Ursprung der Grafik auf dem Bildschirm in der linken oberen Ecke ist.&lt;br /&gt;
&lt;br /&gt;
Breite und Höhe beziehen sich auf das Bild und sind Pixel-Werte. Der Extent (als rectObj) ist schließlich die Bounding Box der Karte in ihrem jeweiligen Koordinatensystem.&lt;br /&gt;
&lt;br /&gt;
Als letzten Wert könnte man übrigens noch ein weiteres rectObj angeben, dass den maximalen Extent angibt, der beim Zoomen nicht verlassen werden darf. Diesen Aufwand muß man aber nicht unbedingt treiben, da das Schlüsselwort =MAXSCALE=  in der Web-Sektion das gleiche leistet.&lt;br /&gt;
&lt;br /&gt;
Im Grunde machen alle Zoomfunktionen nichts anderes, als neue Extents für einen Kartenausschnitt festzulegen. Das bedeutet aber auch, dass Ihre Applikation durcheinander kommen kann, wenn sie beispielsweise gleichzeitig die Möglichkeit zum Zoomen und zum Ändern der Größe der Karte anbietet. Stellen Sie in Ihrem Code sicher, dass Sie in einem solchen Fall zuerst die Änderung des Ausschnitts vornehmen (z.B. Zoomen) und erst danach die Werte für die Kartengeometrie setzen (zum Beispiel Höhe und Breite der Karte).&lt;br /&gt;
&lt;br /&gt;
Das ''Zoomen auf ein Rechteck''  gestaltet sich ähnlich. Über normale Anwendungen im Webbrowser lassen sich zwei angeklickte Punkte nicht übertragen. Diese Funktion kommt also dann zum Tragen, wenn man mit JavaScript oder wie auch immer ein Rechteck aufziehen und entsprechende Werte übergeben kann.&lt;br /&gt;
&lt;br /&gt;
Der aufmerksame Leser kommt natürlich auch auf die Idee, diese Funktion zu benutzen, wenn er auf ein bestimmtes Feature zoomen möchte. Man bestimme dann die Extents des betreffendes Shapes (das geht auch mit MapScript, siehe weiter unten) und zoomt eben auf diese.&lt;br /&gt;
&lt;br /&gt;
Dummerweise geht das nur, wenn man die ''Pixel'' -Koordinaten des Rechtecks kennt, denn die Funktion =zoomRectangle=  wird folgendermaßen genutzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; zoomRectangle (&amp;lt;/math&amp;gt;pixext, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;math&amp;gt;extent);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ist wieder ein rectObj; er gibt die Pixelkoordinaten des Rechtecks an, auf die gezoomt werden soll. Die Breite und die Höhe sind ebenfalls Pixelangaben im Bild. Die Extents schließlich sind wieder ein RectObj, das diesmal die Bounding Box der Karte im Bild im entsprechenden Koordinatensystem angibt.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie einfach auf bestimmte Extents zoomen wollen, ohne vorher in Besitz von Pixelkoordinaten und so weiter zu sein, dann können Sie einfach das Mapfile laden und diese neuen Extents setzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; setExtent (&amp;lt;/math&amp;gt;minx, &amp;lt;math&amp;gt;miny, &amp;lt;/math&amp;gt;maxx, &amp;lt;math&amp;gt;maxy);&lt;br /&gt;
&amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warum diese Methode vier einzelne Koordinaten erwartet und kein RectObj, können wir leider nicht erklären.&lt;br /&gt;
&lt;br /&gt;
Die letzte Zoommethode schließlich ist =zoomScale= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; zoomScale (100000, &amp;lt;/math&amp;gt;imgxy, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;/math&amp;gt;extent);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Wert ist ein SCALE, wie er bereits auf Seite~\pageref{text:mapfile:scale} besprochen worden ist. Beachten Sie bitte, dass so ein Maßstab nicht viel mit dem Maßstab auf einer gedruckten Karte zu tun hat.&lt;br /&gt;
&lt;br /&gt;
Die restlichen Parameter sind wieder die Pixelkoordinaten des Mausklicks, Höhe und Breite des Bildes in Pixeln sowie die Extents des Kartenausschnitts. Auch bei dieser Funktion läßt sich als letzter Parameter wieder als rectObj ein Ausschnitt angeben, aus dem nicht herausgezoomt werden darf.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Eigenschaften und Methoden}&lt;br /&gt;
&lt;br /&gt;
Die restlichen Eigenschaften des mapObj-Objektes dienen dazu, Informationen beziehungsweise Referenzen auf andere Objekte aus dem Mapfile zu ziehen; aber auch, Queries auszuführen. Mehr zu Queries in PHP erfahren Sie weiter unten in dem Abschnitt über Layer. Sie finden die Queries dort (und nicht hier im mapObj, wo sie ausgeführt werden), da die Resultate auf Layer-Ebene eingeholt werden.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Methoden und Eigenschaften, die mapObj bietet, sind im Anhang ab Seite~\pageref{ref:phpms:mapobj} aufgelistet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlerbehandlung==(3)&lt;br /&gt;
&lt;br /&gt;
Jetzt da Sie ein Gefühl dafür haben, wie man Objekte in PHP MapScript anspricht, sollen Sie etwas über die Wege der Fehlerbehandling erfahren, die mit MapServer 4.0 dazugekommen ist.&lt;br /&gt;
&lt;br /&gt;
Bisher sind Fehler einfach aufgetreten und haben meist den weiteren Ablauf des Skripts abgebrochen. Das kann eventuell nicht erwünscht sein; so wäre es zum Beispiel vorstellbar, dass eine Datenbank, die räumliche Daten für einen Layer Ihrer Applikation vorhält, nicht erreichbar ist. Anstatt nun einfach mit einem Fehler abzubrechen, wäre es natürlich angenehmer, wenn man beim Auftreten eines Fehlers dessen Ursache prüfen könnte, nd dann über das weitere Vorgehen entscheiden könnte.&lt;br /&gt;
&lt;br /&gt;
Dieses Vorgehen wird in MapScript 4.0 mit dem neuen Objekt =errorObj=  umgesetzt. Dabei werden Fehler bei ihrem Auftreten in eine interne Liste eingefügt. Aus dieser Liste können sie sodann zu einem Zeitpunkt nach Wahl des Programmierers entnommen und verarbeitet werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns das Beispiel von der offiziellen MapServer-Dokumentationsseite an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
ms_resetErrorList ();&lt;br /&gt;
&amp;lt;math&amp;gt;img = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;math&amp;gt;error = ms_getErrorObj ();&lt;br /&gt;
while (&amp;lt;math&amp;gt;error &amp;amp;&amp;amp; &amp;lt;/math&amp;gt;error -&amp;gt; code != MS_NOERR) {&lt;br /&gt;
  printf (&amp;quot;Error in &lt;br /&gt;
           &amp;lt;math&amp;gt;error -&amp;gt; routine, &amp;lt;/math&amp;gt;error -&amp;gt; message);&lt;br /&gt;
           &amp;lt;math&amp;gt;error = &amp;lt;/math&amp;gt;error -&amp;gt; next ();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst sollten Sie zu Beginn jedes Skriptes die Fehlerliste zurücksetzen; das passiert hier in der ersten Zeile.&lt;br /&gt;
&lt;br /&gt;
Danach holt man sich das globale Fehlerobjekt, über welches dann iteriert wird. Für jeden erzeugten Fehler wird dessen Eigenschaft =code=  abgefragt. Dieser Code ist eine aus einer Liste von Fehlerkonstanten. Falls es sich tatsächlich um einen Fehler handelt -- auch keine Fehler ist ein Fehler, allerdings einer vom Typ =MS_NOERR=  wird eine entsprechende Fehlermeldung ausgegeben. Danach wird zum nächsten unbearbeiteten Fehler in der Liste gesprungen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie nach der Abfrage des nächsten Fehlers keine Möglichkeit mehr haben, zu bereits abgearbeiteten Fehlern zurückzukehren.&lt;br /&gt;
&lt;br /&gt;
Sie finden alle Details zu =errorObj=  in der Referenz ab Seite~\pageref{ref:phpms:errorobj}. Die möglichen Fehlercodes sind außerdem Bestandteil von Tabelle~\ref{tab:ref:mapscript:const}, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt.&lt;br /&gt;
&lt;br /&gt;
==Die layerObj-Klasse==\index{Mapscript!layerObj}\index{layerObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt läßt Sie auf alle Bestandteile einer Layer-Sektion im Mapfile zugreifen.&lt;br /&gt;
&lt;br /&gt;
Dafür müssen Sie natürlich erst einmal wissen, welche Layer sich in einem gegebenen Mapfile befinden. Natürlich könnte man einfach alle Namen in seinem Script hartkodieren. Allerdings kommt man dann schnell in Bedrängnis, wenn sich am Mapfile etwas ändert. Außerdem läßt sich auf diese Weise keine Software schreiben, die sich mit beliebigen Mapfiles auseinandersetzt.&lt;br /&gt;
&lt;br /&gt;
Zuerst einmal können alle Layer in einem Mapfile durch einen Index angesprochen werden, der ihrer Position im Mapfile entspricht. Der erste Layer erhält dabei den Index =0= , der zweite den Index =1=  und so weiter\footnote{Informatiker beginnen immer bei Null mit dem Zählen, nicht bei Eins. Das liegt daran, dass sie sich bei Listen und so weiter nicht dafür interessieren, welche Position ein Element absolut besitzt, sondern welchen Abstand vom Beginn der Liste. Und der ist für das erste Element Null, und so weiter.}. Mit einer Schleife, die über die Anzahl der Layer läuft, kann man also beispielsweise folgendes machen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;num = &amp;lt;/math&amp;gt;map -&amp;gt; numlayers;&lt;br /&gt;
for (&amp;lt;math&amp;gt;i = 0; &amp;lt;/math&amp;gt;i &amp;lt; numlayers; &amp;lt;/math&amp;gt;i++) {&lt;br /&gt;
  &amp;lt;math&amp;gt;layer = &amp;lt;/math&amp;gt;map -&amp;gt; getlayer (&amp;lt;math&amp;gt;i);&lt;br /&gt;
  ... jetzt passieren Dinge mit &amp;lt;/math&amp;gt;layer ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann die Layer aber auch über Ihren Namen ansprechen. Dabei holt man sich zuerst alle Layer-Namen via =getAllLayerNames()=  aus dem mapObj (man erhält ein Array aller Namen zurück), und spricht dann die Layer einzeln mit =getLayerByName()=  an.&lt;br /&gt;
&lt;br /&gt;
Die häufigste Aktion mit einem Layer ist, Queries auszuführen, beziehungsweise danach Query-Ergebnisse aus ihm herauszuholen.&lt;br /&gt;
&lt;br /&gt;
===Queries auf Layer===&lt;br /&gt;
&lt;br /&gt;
Queries liefern seit Version~{3.5} des MapServers keine Objekte vom Type resultObj mehr direkt zurück. Vielmehr werden die Ergebnisse von Queries nun in den Layer-Objekte festgehalten.&lt;br /&gt;
&lt;br /&gt;
Damit Anfragen auf einen Layer gemacht werden können, muß dieser im Mapfile einen =TEMPLATE= -Eintrag besitzen. Dieser Eintrag kann durchaus leer sein. Alternativ zur Angabe auf Layer-Ebene kann =TEMPLATE=  auch nur in einigen (oder allen) =CLASS= es des Mapfiles stehen. Die Queries werden dann nur auf Mitglieder dieser Klasse angewendet.&lt;br /&gt;
&lt;br /&gt;
Am häufigsten werden Queries auf einem mapObj ausgeführt; alle Query-Funktionen lassen sich jedoch auch auf einzelne Layer anwenden. Werden Queries auf mapObj-Objekte angewendet, werden einfach alle in Frage kommenden Layer der Reihe nach mit  der entsprechenden Funktion bedacht.&lt;br /&gt;
&lt;br /&gt;
Queries können auf drei verschiedene Weisen ausgeführt werden: an bestimmten Punkten, mit Hilfe eines Rechtecks und, ganz neu, anhand beliebiger Shapes. Doch wir beginnen mit den Punkt-Queries.&lt;br /&gt;
&lt;br /&gt;
Betrachten Sie folgendes Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; setXY (300000, 500000);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; queryByPoint (&amp;lt;/math&amp;gt;punkt, MS_SINGLE, -1);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird zuerst ein Punkt-Objekt aus den Koordinaten gebaut, die abgefragt werden sollen. Für gewöhnlich kommen diese Koordinaten durch einen Mausklick auf ein Bild in einem Formular zustande. Beachten Sie bitte, dass dieser Punkt im =Koordinatensystem der Karte=  vorliegen muß; die Pixelwerte eines Mausklicks auf eine Karte müssen Sie also zuerst in passende Werte umrechnen.&lt;br /&gt;
&lt;br /&gt;
Danach wird auf dem gewünschten Layer eine Query durchgeführt. Dazu wird der Punkt übergeben, die Art der Anfrage (hier soll nur ein einzelnes Ergebnis erzeugt werden; mit =MS_MULTIPLE=  wären mehrere Ergebnisse möglich), und schließlich ein Puffer. Dieser Puffer ist ein Radius um den Abfragepunkt herum, in den Einheiten der Karte. Ein negativer Wert führt dazu, dass der im Mapfile gesetzte Wert verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Bevor man sich auf eventuelle Resultate stürzt, sollte man prüfen, ob es überhaupt Resultate gab -- die Anfrage kann schließlich auch ins Leere gegangen sein. Dazu prüft man den Rückgabewert der Funktion. Ist dieser =MS_SUCCESS= , so ist alles in Ordnung und man kann fortfahren. Trifft man auf =MS_FAILURE= , so gab es keine Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
Etwas problematisch ist, dass alle Query-Funktionen auch Fehlernachrichten produzieren, wann immer es keine Resultate gab. Dieses Verhalten läßt sich für einzelne Funktionen jedoch mit einem vorangestellten =@=  abstellen. Ein korrekterer Aufruf der obigen Funktion wäre also:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if ((&amp;lt;math&amp;gt;layer -&amp;gt; @queryByPoint (&amp;lt;/math&amp;gt;punkt, MS_SINGLE, -1))&lt;br /&gt;
                                          == MS_SUCCESS) {&lt;br /&gt;
  ... es gab Ergebnisse ...&lt;br /&gt;
} else {&lt;br /&gt;
  ... Fehlerbehandlung ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt können wir uns endlich mit dem Ergebnis des Mausklicks auseinandersetzen. Oder besser: mit den Ergebnissen, denn es können ja mehre sein. Mit =getnumresult()=  bringen wir die Anzahl der Resultate eines Layers in Erfahrung; haben wir nur ein Resultat, ist das nicht nötig. Dieses eine Resultat hat immer den Index =0= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;resultat = &amp;lt;/math&amp;gt;layer -&amp;gt; getResult (0);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;si = &amp;lt;/math&amp;gt;resultat -&amp;gt; shapeindex;&lt;br /&gt;
&amp;lt;math&amp;gt;ti = &amp;lt;/math&amp;gt;resultat -&amp;gt; tileindex;&lt;br /&gt;
&amp;lt;math&amp;gt;ti = &amp;lt;/math&amp;gt;resultat -&amp;gt; classindex;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat-Objekt besitzt also drei Eigenschaften: einen Shapeindex, der die Nummer des Shapes im Shapefile angibt, das dem Layer zugrunde liegt; einen Tileindex, der für gekachelte Shapefiles angibt, in welcher Kachel das Ergebnis aufgetreten ist; und schließlich einen Classindex, der die Class im Layer bezeichnet, für den das Ergebnis aufgetreten ist.&lt;br /&gt;
&lt;br /&gt;
Mit diesen Angaben können Sie dann verfahren, wie Sie es für richtig halten. Sie können zum Beispiel die Daten aus dem =.dbf= -File herausfischen, die dem Shape zugrunde liegen\footnote{Beachten Sie an dieser Stelle die eigenwillige Zählweise in =.dbf= -Dateien, die auch in PHP übernommen wurde: die Zeilen in einer solche Datei sind nicht bei 0 beginnend durchnummeriert, sondern bei 1}. Sie könnten beispielsweise auch auf das gesuchte Shape heranzoomen, indem Sie anhand des gefundenen Index die Bounding Box des Shapes aus dem Shapefile auslesen (siehe auch shapefileObj weiter unten) und diese Bounding Box als neue Extents für die Karte setzen.&lt;br /&gt;
&lt;br /&gt;
Von den einfachen Punkt-Queries kann man nun voranschreiten zu den Anfragen, die über ein Rechteck definiert sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; queryByRect (&amp;lt;/math&amp;gt;rechteck);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Rechteck ist dabei ein rectObj, wie es weiter unten im Text besprochen wird. Die restliche Vorgehensweise entspricht exakt demjenigen bei Punktabfragen.&lt;br /&gt;
&lt;br /&gt;
Hinweise: Rechtecke lassen sich in &amp;quot;`normalem&amp;quot;' HTML nicht erzeugen. Mit JavaScript oder dem ROSA-Applet sieht das schon wieder anders aus. Beachten Sie aber, dass insbesondere öffentliche Institutionen unter Umständen äußerst restriktive Bestimmungen haben, was den Einsatz von JavaScript, dynamischem HTML, Java und so weiter angeht. Auch sicherheitsbewußte Privatanwender haben JavaScript erst gar nicht aktiviert. Überdenken Sie den Einsatz dieser Technologien.&lt;br /&gt;
&lt;br /&gt;
Das gilt auch für die folgende Weise, Queries zu stellen, nämlich anhand eines Shapes, also eines beliebigen Polygons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; queryByShape (&amp;lt;/math&amp;gt;shape);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Art der Query entfaltet Ihren Nutzen weniger anhand von Punkten, die in einem Web-Interface ausgewählt werden können, als vielmehr beim Vergleich von Shapes mit Shapes aus einem anderen Shapefile: wenn Sie beispielsweise ein Shapefile mit Bundesländern haben und eines, indem ohne eine solche Referenzierung Angaben von Verkaufszahlen gespeichert sind, dann lassen sich durch den 'Verschnitt' beider Daten aussagekräftige Ergebnisse erzeugen.&lt;br /&gt;
&lt;br /&gt;
Wie man mit MapScript einzelne Shapes aus einem Shapefile extrahiert erfahren Sie weiter unten bei der Besprechung von shapefileObj. Ein schneller Weg involviert allerdings die Methode =getShape()= , die bereits auf der Ebene des Layers vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Eigenschaften und Methoden}&lt;br /&gt;
&lt;br /&gt;
Die weiteren Funktionen in layerObj dienen im wesentlichen dazu, Zugriff auf die einzelnen Werte eines Layers zu erhalten, beziehungsweise auf die weiteren Objekte darin bezug nehmen zu können, insbesondere auf die Classes im Layer.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Methoden und Eigenschaften, die layerObj bietet, sind im Anhang ab Seite~\ref{ref:phpms:layerobj} aufgelistet.&lt;br /&gt;
&lt;br /&gt;
==Die classObj-Klasse==\index{Mapscript!classObj}\index{classObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt entspricht einer Class innerhalb eines Layers. Mit einem classObj können Sie im wesentlichen Farben und Symbole für eine Class setzen -- insbesondere aber die Expressions für eine Class.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel, wie man das verwenden kann: Nehmen wir an, Sie haben einen Datenbestand, der Ihnen die Deutschland in lauter kleine Gebiete einteilt. In der dazu gehörigen ''.dbf'' -Datei haben Sie in einer Spalte für jedes Gebiet den prozentualen Anteil an Waldfläche gespeichert. Diese Spalte trägt den Namen =WALD= .&lt;br /&gt;
&lt;br /&gt;
In Ihrer Applikation haben Sie nun ein Eingabefeld, das es dem Benutzer ermöglicht, eine Anzahl von Grün-Abstufungen zu bestimmen, in die der Layer eingeteilt werden soll. Gibt der Benutzer beispielsweise =4=  ein, werden dem Layer vier Klassen hinzugefügt, die von grün bis weiß vier Farbstufen annehmen.&lt;br /&gt;
&lt;br /&gt;
Sie errechnen in der PHP-Seite dann die Unterteilung in vier Grünstufen und setzen vier verschiedene Classes.&lt;br /&gt;
&lt;br /&gt;
==Die imageObj-Klasse==\index{Mapscript!imageObj}\index{imageObj}&lt;br /&gt;
&lt;br /&gt;
Diese Objekte werden niemals 'von Hand' erzeugt, sondern immer nur durch den Aufruf von Methoden anderer MapScript-Objekte. Bei diesen Image-Objekten handelt es sich nicht um Bild-Dateien, sondern lediglich um die Bilddaten, die in einem Puffer im Speicher liegen und noch darauf warten, gespeichert zu werden.&lt;br /&gt;
&lt;br /&gt;
Alle =draw= -Methoden von mapObj erzeugen ein imageObj. Am häufigsten wird danach die Methode =saveWebImage()=  aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;image = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;math&amp;gt;url = &amp;lt;/math&amp;gt;image -&amp;gt; saveWebImage (MS_JPEG, 0, 0, 90);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter der Methode ist das gewünschte Bildformat, das meistens =MS_PNG=  sein wird, ab und zu =MS_JPEG=  und nur, wenn es sich nicht vermeiden läßt, =MS_GIF= .&lt;br /&gt;
&lt;br /&gt;
Die beiden folgenden Parameter legen eine Transparenz der Hintergrundfarbe bzw. ein Interlacing für das Bild fest. Der letzte (optionale) Parameter legt für Bildformate, die eine Kompression zur Verfügung stellen, den Grad dieser Kompression fest. Werte zwischen 0 und 100 sind hier möglich.&lt;br /&gt;
&lt;br /&gt;
Eine vollständige Aufzählung aller Methoden dieses Objektes finden Sie im Anhang ab Seite~\pageref{ref:phpms:imageobj}.&lt;br /&gt;
&lt;br /&gt;
==Die labelObj-Klasse==\index{Mapscript!labelObj}\index{labelObj}&lt;br /&gt;
&lt;br /&gt;
Labels befinden sich innerhalb von classObj-Objekten. Diese Klasse kennt erstaunlicherweise keine einzige Methode außer =set()= , dafür eine große Menge von Eigenschaften. In der Referenz finden Sie ab Seite~\pageref{ref:phpms:labelobj} eine ausführliche Aufzählung.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet übrigens auch, dass es keinen Konstruktor für diese Klasse gibt und demnach keine Möglichkeit, ein labelObj 'von Hand' zu erstellen.&lt;br /&gt;
&lt;br /&gt;
==Die webObj-Klasse==\index{Mapscript!webObj}\index{webObj}&lt;br /&gt;
&lt;br /&gt;
Ebenso wie beim labelObj gibt es auch für diese Klasse keinen Konstruktor und keine weiteren Methoden neben der =set()= -Methode. In der Referenz im Anhang finden Sie ab Seite~\pageref{ref:phpms:webobj} eine Liste aller Eigenschaften dieser Klasse.&lt;br /&gt;
&lt;br /&gt;
webObj-Objekte finden Sie immer als Bestandteil eines mapObj.&lt;br /&gt;
&lt;br /&gt;
==Die referenceMapObj-Klasse==\index{Mapscript!referenceMapObj}\index{referenceMapObj}&lt;br /&gt;
&lt;br /&gt;
Auch Objekte dieser Klasse kommen nur innerhalb eines mapObj vor, es gibt keinen Konstruktor und keine Methode außerhalb von =set()= .&lt;br /&gt;
&lt;br /&gt;
In der Referenz ab Seite~\pageref{ref:phpms:referencemapobj} finden Sie eine Liste aller Eigenschaften dieser Klasse.&lt;br /&gt;
&lt;br /&gt;
==Die colorObj-Klasse==\index{Mapscript!colorObj}\index{colorObj}&lt;br /&gt;
&lt;br /&gt;
Jede Karte verfügt über eine bestimmte Farbpalette. Diese Palette wird beim Generieren der Karte erstellt.&lt;br /&gt;
&lt;br /&gt;
Neue Farben lassen sich der Palette hinzufügen, indem man Objekte der Klasse colorObj erzeugt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;weiss = ms_newColorObj ();&lt;br /&gt;
&amp;lt;/math&amp;gt;weiss -&amp;gt; setRGB (255, 255, 255);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Farbe kann dann an den Stellen, wo es möglich und nötig ist, verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==Die pointObj-Klasse==\index{Mapscript!pointObj}\index{pointObj}&lt;br /&gt;
&lt;br /&gt;
Punkte werden an diversen Stellen in MapScript für verschiedene Dinge benötigt. Wann immer eine Funktion die zwei Koordinaten eines Punktes übergeben bekommt, wird ein pointObj verlangt. Sehen Sie sich beispielsweise die Verwendung von =queryByPoint=  im Abschnitt über das Objekt =layerObj=  an.&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt besitzt aber noch einige andere Methoden in MapScript. Insbesondere kann man damit die Abstände von Punkten zu anderen Punkten, zu Linien und zu Polygonen bestimmen; außerdem lassen sich einzelne Punkte mithilfe von Objekten der Klasse projectionObj projizieren. Des weiteren kann man einzelne Punkte aus Linien-Objekten extrahieren (siehe lineObj).&lt;br /&gt;
&lt;br /&gt;
pointObj gehört zu den Klassen, deren Speicher nach Gebrauch explizit freigegeben werden muß (siehe Seite~\pageref{text:mapscript:memory}).&lt;br /&gt;
&lt;br /&gt;
Die Referenz zu allen Methoden von pointObj finden Sie auf Seite~\pageref{ref:phpms:pointobj}.&lt;br /&gt;
&lt;br /&gt;
==Die lineObj-Klasse==\index{Mapscript!lineObj}\index{lineObj}&lt;br /&gt;
&lt;br /&gt;
Linien lassen sich entweder von Hand konstruieren (indem man der Reihe nach einzelne Punkte hinzufügt), oder aber aus Shapes der Klasse shapeObj extrahieren. Außerdem lassen sich Linien natürlich ebenfalls projizieren.&lt;br /&gt;
&lt;br /&gt;
lineObj gehört zu den Klassen, deren Speicher nach Gebrauch explizit freigegeben werden muß (siehe Seite~\pageref{text:mapscript:memory}).&lt;br /&gt;
&lt;br /&gt;
Die Referenz zu allen Methoden von lineObj finden Sie auf Seite~\pageref{ref:phpms:lineobj}.&lt;br /&gt;
&lt;br /&gt;
==Die projectionObj-Klasse==\index{Mapscript!projectionObj}\index{projectionObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt beschreibt einen Projektions-Abschnitt in einem Mapfile. Aber es kann auch jenseits von Mapfiles verwendet werden, um einzelne Punktkoordinaten umzuprojizieren.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel projiziert einen einzelnen Punkt von einer Längen-/Breitenangabe in einen Punkt im UTM 32-System:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;projin = ms_newProjectionObj (&amp;quot;proj=latlong&amp;quot;);&lt;br /&gt;
&amp;lt;/math&amp;gt;projout = ms_newProjectionObj (&amp;quot;proj=utm,zone=32,ellps=WGS84,&lt;br /&gt;
                                 datum=WGS84,no_defs&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; setXY (32.0, 51.0);&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = &amp;lt;/math&amp;gt;punkt -&amp;gt; project ();&lt;br /&gt;
printf (&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die genauen Parameter, die Sie für die von Ihnen gewünschte Projektion verwenden müssen, finden Sie in der Dokumentation der Projektionsbibliothek proj.4.&lt;br /&gt;
&lt;br /&gt;
==Die shapefileObj-Klasse==\index{Mapscript!shapefileObj}\index{shapefileObj}&lt;br /&gt;
&lt;br /&gt;
Diese Klasse dient dazu, Shapefiles direkt manipulieren zu können. Sie können ein Shapefile als Objekt öffnen, einzelne Shapes referenzieren, die Eigenschaften des Shapefiles auslesen und sogar neue Shapes an das Shapefile anhängen und ganz neue Shapfiles erschaffen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie kein mapObj erzeugen müssen, um Shapefiles auf diese Weise zu bearbeiten. Das shapefileObj ist unabhängig von den MapServer-verwandten Klassen in MapScript, kann aber natürlich mit diesen zusammen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Referenz für alle Eigenschaften und Methoden von shapefileObj finden Sie ab Seite~\ref{ref:phpms:shapefileobj}.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel gibt eine simple Statistik über alle Shapefiles aus, die es im aktuellen Verzeichnis finden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
foreach (glob (&amp;quot;*.shp&amp;quot;) as &amp;lt;math&amp;gt;shpfname) {&lt;br /&gt;
  &amp;lt;math&amp;gt;shpf = ms_newShapefileObj (&amp;lt;/math&amp;gt;shpfname, -1);&lt;br /&gt;
  &amp;lt;math&amp;gt;noshapes = &amp;lt;/math&amp;gt;shpf -&amp;gt; numshapes;&lt;br /&gt;
  &amp;lt;math&amp;gt;shpftype = &amp;lt;/math&amp;gt;shpf -&amp;gt; type;&lt;br /&gt;
  &amp;lt;math&amp;gt;bounds = &amp;lt;/math&amp;gt;shpf -&amp;gt; bounds;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Anzahl der Shapes: &lt;br /&gt;
          &amp;quot;Typ des Shapefiles: &lt;br /&gt;
          &amp;quot;Extents: &lt;br /&gt;
          &amp;lt;math&amp;gt;noshapes, &amp;lt;/math&amp;gt;shpftype,&lt;br /&gt;
          &amp;lt;math&amp;gt;bounds -&amp;gt; minx, &amp;lt;/math&amp;gt;bounds -&amp;gt; miny,&lt;br /&gt;
          &amp;lt;math&amp;gt;bounds -&amp;gt; maxx, &amp;lt;/math&amp;gt;bounds -&amp;gt; maxy);&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/math&amp;gt;shpf -&amp;gt; free ();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Struktur von PHP MapScript-Seiten==&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit PHP MapScript das Verhalten einer 'normalen' MapServer-Applikation nachbilden möchten, kann Ihnen das folgende Schema einige Anhaltspunkte geben, wie beim Aufbau einer solchen Applikation vorgegangen werden kann.&lt;br /&gt;
&lt;br /&gt;
Weitere Optionen für Ihre Applikation müssen an sinnvollen Stellen in das Gerüst eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung ist natürlich kein in Stein gemeißeltes Gesetz, sondern kann von Fall zu Fall abgeändert werden. Es bietet aber eine gute Orientierungshilfe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#Prüfen der übergebenen Parameter auf sinnvolle Werte&lt;br /&gt;
#Laden des Mapfiles&lt;br /&gt;
#Fallunterscheidung nach gewünschtem Modus:&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	##Simples Browsen (Pan) der Karte:&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Koordinaten des Mausklicks  		##&lt;br /&gt;
*Zoomen auf den Punkt mit einer Zoomtiefe von 1  		&lt;br /&gt;
	##Zoomen auf/um den betreffenden Punkt&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Koordinaten des Mausklicks  		##&lt;br /&gt;
*Zoomen auf den Punkt mit dem übergebenen Zoomfaktor  		&lt;br /&gt;
	##Zoomen auf das angeklickte Shape&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Shapenummer mittels queryByPoint  		##&lt;br /&gt;
*Öffnen des entsprechenden Shapefiles und Ermitteln der Extents des angeklickten Shapes  		##&lt;br /&gt;
*Zoomen auf das Shape mittels zoomByRect  		&lt;br /&gt;
	##Query auf den geklickten Punkt&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Kartenkoordinaten des angeklickten Punktes (oder mehrerer Punkte, falls es ein queryByRect ist)  		##&lt;br /&gt;
*Ausführen der Query  		##&lt;br /&gt;
*Auslesen des Ergebnis' (oder der Ergebnisse) aus einem oder mehreren Layer-Objekten  		##&lt;br /&gt;
*Präsentation der Ergebnisse  		&lt;br /&gt;
	&lt;br /&gt;
#Rendern der Karte und Abspeichern in einer Datei&lt;br /&gt;
#Eintragen des URL des fertigen Bildes in den entsprechenden HTML-Tag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Speichern von Map-Objekten in PHP-Sessions==&lt;br /&gt;
&lt;br /&gt;
Leider können Objekte aus PHP-MapScript (insbesondere ein mapObj) nicht in Sessions gespeichert werden. Der Grund dafür ist, dass die Objekte in PHP-MapScript keine 'reinen' PHP-Objekte sind, sondern lediglich als Wrapper um die C-Daten\-struk\-turen des MapServer-Quellcodes angelegt sind. Das führt dazu, dass beim Speichern in einer Sitzungsvariablen lediglich der Wrapper gespeichert wird, nicht aber das darunter liegende Objekt.&lt;br /&gt;
&lt;br /&gt;
Man muß also entweder (um beim Beispiel eines mapObj zu beiben) die ''vorgenommenen Änderungen''  auf eine genehme Art und Weise speichern und mitschleifen, um diese dann jedesmal auf ein neu erstelltes mapObj anzuwenden; oder man speichert die fertige Karte als Datei im System ab und speichert den Dateinamen der Karte in der Sitzungsvariablen.&lt;br /&gt;
&lt;br /&gt;
==Speicherverwaltung mit MapScript==(4)&lt;br /&gt;
&lt;br /&gt;
Die Speicherverwaltung aller MapScript-Objekte, die im Zusammenhang mit dem Mapfile stehen, geschieht automatisch. Sie müssen also nicht für jedes Objekt Speicher anfordern und wieder freigeben.&lt;br /&gt;
&lt;br /&gt;
Etwas anders verhält es sich bei Objekten zu Shapefiles und allen geometrischen Objekten wie Punkten, Linien und so weiter. Das Anfordern von Speicher entfällt zwar. Allerdings sollten alle Objekte dieser am Ende (also nachdem man Gebrauch von ihnen gemacht hat und sie nicht mehr benötigt) explizit zerstört und alle verwendeten Resourcen freigegeben werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; free ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwar wird jeder Speicher, der innerhalb eines PHP-Skriptes benutzt wird, nach dem Abarbeiten der Seite automatisch wieder freigegeben. Allerdings kann bei beim exzessiven Gebrauch von Objekten innerhalb einer Seite vielleicht in Speicherschwierigkeiten kommen.&lt;br /&gt;
&lt;br /&gt;
Außerdem können Sie in Ihrem Programm zwar keine Probleme mit dem Speicher haben. Denken Sie aber immer daran, dass Kollegen, Freunde, Mitarbeiter und so weiter später vielleicht auf die Idee kommen können, das Programm abzuändern und zu erweitern. Wenn Sie von vornherein vernünftig mit dem Speicher umgegangen sind, so sind Sie auf der sicheren Seite. Es zeugt darüber hinaus von einem sauberen Programmierstil.&lt;br /&gt;
&lt;br /&gt;
=Weitere Sprachen=&lt;br /&gt;
&lt;br /&gt;
MapScript kann mit verschiedenen Sprachen genutzt werden. Neben PHP sind die populärsten Perl, Java und Python.&lt;br /&gt;
&lt;br /&gt;
Die MapServer-Entwickler bedienen sich bei diesen Sprachen des Interface-Generators SWIG~[[http:website:swig]]. Die Verwendung von SWIG und die Erstellung von MapScript-Modulen für andere Programmiersprachen wird im Anhang besprochen.&lt;br /&gt;
&lt;br /&gt;
==Perl==&lt;br /&gt;
&lt;br /&gt;
Zu Perl gibt es unglaublich viel Literatur. Nichts falsch machen kann man wohl mit~[[wall:1996:perl5]], dem berühmten Camel Book. Es ist auch auf deutsch erschienen.&lt;br /&gt;
&lt;br /&gt;
==Java==&lt;br /&gt;
&lt;br /&gt;
Java ist eine Sprache, aus der ein unglaublicher Hype hervorgegangen ist. Die Literatur, die sich mit Java auseinandersetzt, ist dermaßen umfangreich, dass Sie sich von dem Buchhändler Ihres Vertrauens beraten lassen sollten.&lt;br /&gt;
&lt;br /&gt;
==Python==&lt;br /&gt;
&lt;br /&gt;
Python hat sich einen Namen als einfache, strukturierte und schnell zu lernende Programmiersprache gemacht. Wer des Englischen mächtig ist, ist mit der Lektüre von~[[lutz:1999:python]] recht gut beraten; das Buch ist auch auf deutsch erschienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Java-Applets}\index{Applets}(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Mapplet=\index{Mapplet}(2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=ROSA=(3)\index{ROSA}&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_6&amp;diff=34430</id>
		<title>HBUMNMapServer ger Capter 6</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_6&amp;diff=34430"/>
		<updated>2009-01-23T10:14:05Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Laden des Moduls */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= MapScript =&lt;br /&gt;
(1)\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
Bisher haben Sie den MapServer als Applikation kennengelernt, die in einem Webserver wie zum Beispiel Apache arbeitet, und direkt über Parameter des URL aufgerufen und in ihrem Verhalten beeinflußt werden kann.&lt;br /&gt;
&lt;br /&gt;
Man kann sich aber natürlich auch vorstellen, die Funktionen von MapServer -- das Lesen von Mapfiles, das Rendern der Karten und so weiter -- auch aus eigenen Programmen nutzen zu wollen, natürlich auch solchen, die nicht in einem Webserver laufen sollen. Dazu müßte man diese Funktionen separat zur Verfügung stellen, beispielsweise in einer eigenen Bibliothek, auf die dann aus anderen Programmiersprachen zugegriffen werden kann. Diese Bibliothek existiert bereits und trägt den Namen MapScript.&lt;br /&gt;
&lt;br /&gt;
Zu den Sprachen wie Java, Python, Perl und einigen anderen, die mit MapScript benutzt werden können, gesellt sich auch PHP. PHP MapScript soll im Folgenden als Anknüpfungspunkt für die Erklärung von MapScript dienen -- die genaue Terminologie für einzelne Programmiersprachen entnehmen Sie bitte der jeweilgen Dokumentation der Sprache bzw. den Beispielen, die dem MapServer-Quellcode beiliegen.&lt;br /&gt;
&lt;br /&gt;
=PHP MapScript=(2)\index{PHP MapScript}\index{MapScript!PHP}&lt;br /&gt;
&lt;br /&gt;
Ich erspare dem Leser die an dieser Stelle üblichen Hymnen auf PHP\footnote{Beziehungsweise die üblichen Flames. Die Sprache ist definitiv nichts für Puristen oder Entwickler mit eng gesteckten Vorgaben, was den Resourcenverbrauch angeht.} und seine Flexibilität als Sprache für Webanwendungen. Es ist in der Tat sehr weit verbreitet. Das ist (neben der besonderen Pflege, die gerade diese Sprachanbindung erfährt) auch der Grund, warum wir an dieser Stelle detailliert auf PHP MapScript eingehen, und nicht beispielsweise auf Perl.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle gehen wir nicht darauf ein, wie Sie PHP installieren, oder wie Sie Ihren Webserver korrekt für den Einsatz von PHP konfigurieren. Wie man das tut, erfahren Sie in der Dokumentation von PHP bzw. Ihres Webservers. Die Installation von PHP MapScript wird im Anhang dieses Handbuches abgehandelt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass PHP MapScript im Moment zwingend voraussetzt, dass Sie PHP ''nicht''  als Modul laden, sondern als CGI-Programm einsetzen. Es kann ansonsten zu nicht vorhersehbaren Komplikationen kommen.&lt;br /&gt;
&lt;br /&gt;
Als erstes deutschsprachiges Einsteigerbuch zu PHP eignet sich beispielsweise~[[theis:2000:php]]; allerdings gibt es eine solche Unzahl an Büchern über diese Sprache, dass eine persönliche Auswahl im Buchladen erfolgen sollte. Die Website zur PHP [[http:website:php]] stellt ausführliche Dokumentation bereits, die interessanterweise auch vollständig ins deutsche übersetzt ist.&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist es eine gute Idee, sich mit der FAQ von =de.comp.lang.php= ~[[faq:dclp]]  auseinanderzusetzen, der deutschsprachigen Newsgroup zu PHP, die in einem eigenen Kapitel auch auf Sicherheitsbelange eingeht.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{mapscript-hyk}{Ein Beispiel für eine PHP MapScript Anwendung sind die Hydrogeologischen Karten Brandenburg}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
==Laden des Moduls==&lt;br /&gt;
&lt;br /&gt;
Um die MapScript-Funktionen in einer PHP-Seite verwenden zu können, muss das Modul dafür geladen werden. Das geschieht ganz einfach durch ''dl'' :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 dl (&amp;quot;php_mapscript.so&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies sollte die erste Zeile sein, die Sie in jede Seite einfügen, die MapScript-Funktionen benutzt. Sollten Sie sich unter Windows befinden, ändert sich diese Zeile leicht in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 dl (&amp;quot;php_mapscript.dll&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine portable Anwendung schreiben sollen, ist es demnach angebracht, gleich zu Beginn des Skripts auf das verwendete Betriebssystem zu prüfen und dann die korrekte Datei zu laden.&lt;br /&gt;
&lt;br /&gt;
==Setzen von Objekt-Eigenschaften==&lt;br /&gt;
&lt;br /&gt;
Bevor Sie auch nur eine einzige Klasse aus MapScript kennenlernen, möchte ich zeigen, wie man die Eigenschaften von Objekten setzt, da diese Methode für alle Objekte (die sie unterstützen) gleich ist.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; set (&amp;quot;name&amp;quot;, &amp;quot;gruenflaechen&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit diesem Aufruf wird der Name eines Layer-Objektes auf =gruenflaechen=  gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der 'korrekte' objektorientierte Ansatz wäre natürlich gewesen, dafür eine eigene Routine =setName()=  zu implementieren. Da einige Klassen in MapScript jedoch über eine ziemlich große Anzahl an Eigenschaften verfügen, hat man sich auf diese Methode beschränkt.&lt;br /&gt;
&lt;br /&gt;
Das Setzen von Eigenschaften auf diese Weise funktioniert nur für Eigenschaften, die nicht =read-only=  sind. Nicht jedes Objekt implementiert zudem die =set()= -Methode. In der Referenz im Anhang dieses Handbuchs sehen Sie, welche Klasse eine solche Methode zur Verfügung stellt.&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus haben einige Klassen für einige Eigenschaften doch noch eigene Methoden implementiert. Studieren Sie die Referenz im Anhang, um herauszufinden, für welche Klassen und Eigenschaften das gilt.&lt;br /&gt;
&lt;br /&gt;
==Formulareingaben in PHP verarbeiten==&lt;br /&gt;
&lt;br /&gt;
In älteren PHP-Versionen war es kein Problem, URL-Parameter einfach als Variable in ein PHP-Skript zu übernehmen. Wenn ein Aufruf also etwa so aussah:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
.../skript.php?name=Calli&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann konnte man ohne Probleme das folgende in sein Skript schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
echo &amp;lt;/math&amp;gt;name;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das produzierte dann die Ausgabe =Calli= .&lt;br /&gt;
&lt;br /&gt;
In neueren Fassungen von PHP\footnote{Und aufgrund der bekannt gewordenen Sicherheitslücken möchte man eine alte Version nicht benutzen. Verwenden Sie nichts unter 4.3.3!} geht das so nicht mehr. Weil es durch diverse Tricksereien möglich war, globale PHP-Variablen von außen zu überschreiben, und weil man die Programmierer zwingen wollte, sich mit den Werten in ihren Variablen genauer zu befassen, muß man sich jeden Wert nun explizit aus einem Array holen, das den Namen =\&amp;lt;math&amp;gt;_GET[]=  trägt.&lt;br /&gt;
&lt;br /&gt;
Für unser obiges Beispiel benötigen Sie dann also folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;dername = &amp;lt;/math&amp;gt;_GET ['name'];&lt;br /&gt;
echo &amp;lt;/math&amp;gt;dername;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manchmal werden durch eine Eingabemöglichkeit in einem HTML-Formular mehrere Werte übergeben. Ein Beispiel dafür ist ein angeklicktes Bild, wie es etwa unsere Karte ist -- ein Klick produziert natürlich eine X- und eine Y-Koordinate. PHP verhält sich an dieser Stelle etwas unerwartet. Betrachten wir das folgende Bild in einem HTML-Formular:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;image&amp;quot; name=&amp;quot;img&amp;quot; src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach einem Klick finden Sie im URL zwei Werte, namentlich =img.x=  und =img.y= . Diese beiden Variablen werden Sie aber im Array =\&amp;lt;math&amp;gt;_GET[]=  vergeblich suchen, denn für PHP werden die Punkte durch Unterstriche ersetzt. Sie müssen sich also =img_x=  und =img_y=  aus dem Array holen.&lt;br /&gt;
&lt;br /&gt;
Es ist übrigens immer angezeigt, den Wert jeder Variablen, die von außen belegt wird, eingehend auf seine Sinnhaftigkeit zu prüfen.&lt;br /&gt;
&lt;br /&gt;
==Die mapObj-Klasse==\index{Mapscript!mapObj}\index{mapObj}&lt;br /&gt;
&lt;br /&gt;
Als nächstes möchten wir betrachten, wie MapScript ein Mapfile behandelt. Betrachten Sie das erste Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;image = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;math&amp;gt;imageurl = &amp;lt;/math&amp;gt;image -&amp;gt; saveWebImage (MS_PNG, 1, 1, 0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der ersten Zeile wird ein =mapObj=  erzeugt, das auf ein bereits existentes Mapfile zugreift. Danach wird daraus ein =ImageObj=  erzeugt, es wird also die Karte gezeichnet. Dabei werden die gesetzten Werte für die Extents aus dem Mapfile übernommen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass dadurch noch keine fertige Bild''datei''  erzeugt wird. Die Karte existiert zu diesem Zeitpunkt nur als Puffer im Speicher.&lt;br /&gt;
&lt;br /&gt;
In einer Datei tatsächlich gespeichert wird das Bild in der letzten Zeile, in unserem Beispiel als Bild im PNG-Format. Die Rückgabe der Funktion ist der URL für den Webserver, unter der er das Bild ausliefern kann.&lt;br /&gt;
&lt;br /&gt;
Man kann daher weiter unten in der Seite folgendes HTML verwenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;lt;?php echo &amp;lt;math&amp;gt;imageurl; ?&amp;gt;&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch wird der betreffende URL in den =&amp;lt;img&amp;gt;= -Tag eingefügt und an den Client ausgeliefert. Das Resultat ist natürlich ein zentriertes Bild der Karte im Webbrowser.&lt;br /&gt;
&lt;br /&gt;
Auf die gleiche Weise werden übrigens auch Legenden, Maßstäbe und Referenzkarten erzeugt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;img_legend = &amp;lt;/math&amp;gt;map -&amp;gt; drawLegend ();&lt;br /&gt;
&amp;lt;math&amp;gt;img_scalebar = &amp;lt;/math&amp;gt;map -&amp;gt; drawScaleBar ();&lt;br /&gt;
&amp;lt;math&amp;gt;img_refmap = &amp;lt;/math&amp;gt;map -&amp;gt; drawReferenceMap ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch diese Bildobjekte werden wieder über deren Methode =saveWebImage=  abgespeichert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Zoomen}&lt;br /&gt;
&lt;br /&gt;
Das Zoomen in eine Karte kann auf drei Weisen geschehen: Zoomen in Richtung eines Punktes, Zoomen auf ein Rechteck und Zoomen auf einen Punkt in einem bestimmten Maßstab.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den ersten Fall. Wir gehen davon aus, dass wir ein Bild in einem HTML-Formular eingebettet hatten, und dieses Bild wie gerade beschrieben per PHP Mapscript erzeugt hatten. Wurde das Bild angeklickt, werden die Pixelkoordinaten des Klicks über das Formular mit übergeben. Gehen wir von einem festen Zoomfaktor von 2 aus (diesen Wert legen wir für dieses Beispiel jetzt fest), können wir mit diesen Pixeln folgendes tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/file.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; zoomPoint (2, &amp;lt;/math&amp;gt;imgxy, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;math&amp;gt;extent);&lt;br /&gt;
&amp;lt;math&amp;gt;img = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird in seinem ursprünglichen Zustand geladen. Dann werden der Zoomfunktion die nötigen Parameter übergeben: zuerst der Zoomfaktor, den wir hier mit 2 festlegen, aber natürlich auch im Formular einstellen lassen können. Der folgende Wert ist ein pointObj, das die Bildkoordinaten des angeklickten Punktes darstellt. Falls Sie mit diesen Werten irgendwelche Berechnungen anstellen wollen, beachten Sie, dass der Ursprung der Grafik auf dem Bildschirm in der linken oberen Ecke ist.&lt;br /&gt;
&lt;br /&gt;
Breite und Höhe beziehen sich auf das Bild und sind Pixel-Werte. Der Extent (als rectObj) ist schließlich die Bounding Box der Karte in ihrem jeweiligen Koordinatensystem.&lt;br /&gt;
&lt;br /&gt;
Als letzten Wert könnte man übrigens noch ein weiteres rectObj angeben, dass den maximalen Extent angibt, der beim Zoomen nicht verlassen werden darf. Diesen Aufwand muß man aber nicht unbedingt treiben, da das Schlüsselwort =MAXSCALE=  in der Web-Sektion das gleiche leistet.&lt;br /&gt;
&lt;br /&gt;
Im Grunde machen alle Zoomfunktionen nichts anderes, als neue Extents für einen Kartenausschnitt festzulegen. Das bedeutet aber auch, dass Ihre Applikation durcheinander kommen kann, wenn sie beispielsweise gleichzeitig die Möglichkeit zum Zoomen und zum Ändern der Größe der Karte anbietet. Stellen Sie in Ihrem Code sicher, dass Sie in einem solchen Fall zuerst die Änderung des Ausschnitts vornehmen (z.B. Zoomen) und erst danach die Werte für die Kartengeometrie setzen (zum Beispiel Höhe und Breite der Karte).&lt;br /&gt;
&lt;br /&gt;
Das ''Zoomen auf ein Rechteck''  gestaltet sich ähnlich. Über normale Anwendungen im Webbrowser lassen sich zwei angeklickte Punkte nicht übertragen. Diese Funktion kommt also dann zum Tragen, wenn man mit JavaScript oder wie auch immer ein Rechteck aufziehen und entsprechende Werte übergeben kann.&lt;br /&gt;
&lt;br /&gt;
Der aufmerksame Leser kommt natürlich auch auf die Idee, diese Funktion zu benutzen, wenn er auf ein bestimmtes Feature zoomen möchte. Man bestimme dann die Extents des betreffendes Shapes (das geht auch mit MapScript, siehe weiter unten) und zoomt eben auf diese.&lt;br /&gt;
&lt;br /&gt;
Dummerweise geht das nur, wenn man die ''Pixel'' -Koordinaten des Rechtecks kennt, denn die Funktion =zoomRectangle=  wird folgendermaßen genutzt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; zoomRectangle (&amp;lt;/math&amp;gt;pixext, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;math&amp;gt;extent);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ist wieder ein rectObj; er gibt die Pixelkoordinaten des Rechtecks an, auf die gezoomt werden soll. Die Breite und die Höhe sind ebenfalls Pixelangaben im Bild. Die Extents schließlich sind wieder ein RectObj, das diesmal die Bounding Box der Karte im Bild im entsprechenden Koordinatensystem angibt.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie einfach auf bestimmte Extents zoomen wollen, ohne vorher in Besitz von Pixelkoordinaten und so weiter zu sein, dann können Sie einfach das Mapfile laden und diese neuen Extents setzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;/math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; setExtent (&amp;lt;/math&amp;gt;minx, &amp;lt;math&amp;gt;miny, &amp;lt;/math&amp;gt;maxx, &amp;lt;math&amp;gt;maxy);&lt;br /&gt;
&amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warum diese Methode vier einzelne Koordinaten erwartet und kein RectObj, können wir leider nicht erklären.&lt;br /&gt;
&lt;br /&gt;
Die letzte Zoommethode schließlich ist =zoomScale= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;/path/to/mapfile.map&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;map -&amp;gt; zoomScale (100000, &amp;lt;/math&amp;gt;imgxy, &amp;lt;math&amp;gt;breite, &amp;lt;/math&amp;gt;hoehe, &amp;lt;/math&amp;gt;extent);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Wert ist ein SCALE, wie er bereits auf Seite~\pageref{text:mapfile:scale} besprochen worden ist. Beachten Sie bitte, dass so ein Maßstab nicht viel mit dem Maßstab auf einer gedruckten Karte zu tun hat.&lt;br /&gt;
&lt;br /&gt;
Die restlichen Parameter sind wieder die Pixelkoordinaten des Mausklicks, Höhe und Breite des Bildes in Pixeln sowie die Extents des Kartenausschnitts. Auch bei dieser Funktion läßt sich als letzter Parameter wieder als rectObj ein Ausschnitt angeben, aus dem nicht herausgezoomt werden darf.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Eigenschaften und Methoden}&lt;br /&gt;
&lt;br /&gt;
Die restlichen Eigenschaften des mapObj-Objektes dienen dazu, Informationen beziehungsweise Referenzen auf andere Objekte aus dem Mapfile zu ziehen; aber auch, Queries auszuführen. Mehr zu Queries in PHP erfahren Sie weiter unten in dem Abschnitt über Layer. Sie finden die Queries dort (und nicht hier im mapObj, wo sie ausgeführt werden), da die Resultate auf Layer-Ebene eingeholt werden.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Methoden und Eigenschaften, die mapObj bietet, sind im Anhang ab Seite~\pageref{ref:phpms:mapobj} aufgelistet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlerbehandlung==(3)&lt;br /&gt;
&lt;br /&gt;
Jetzt da Sie ein Gefühl dafür haben, wie man Objekte in PHP MapScript anspricht, sollen Sie etwas über die Wege der Fehlerbehandling erfahren, die mit MapServer 4.0 dazugekommen ist.&lt;br /&gt;
&lt;br /&gt;
Bisher sind Fehler einfach aufgetreten und haben meist den weiteren Ablauf des Skripts abgebrochen. Das kann eventuell nicht erwünscht sein; so wäre es zum Beispiel vorstellbar, dass eine Datenbank, die räumliche Daten für einen Layer Ihrer Applikation vorhält, nicht erreichbar ist. Anstatt nun einfach mit einem Fehler abzubrechen, wäre es natürlich angenehmer, wenn man beim Auftreten eines Fehlers dessen Ursache prüfen könnte, nd dann über das weitere Vorgehen entscheiden könnte.&lt;br /&gt;
&lt;br /&gt;
Dieses Vorgehen wird in MapScript 4.0 mit dem neuen Objekt =errorObj=  umgesetzt. Dabei werden Fehler bei ihrem Auftreten in eine interne Liste eingefügt. Aus dieser Liste können sie sodann zu einem Zeitpunkt nach Wahl des Programmierers entnommen und verarbeitet werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns das Beispiel von der offiziellen MapServer-Dokumentationsseite an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
ms_resetErrorList ();&lt;br /&gt;
&amp;lt;math&amp;gt;img = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;math&amp;gt;error = ms_getErrorObj ();&lt;br /&gt;
while (&amp;lt;math&amp;gt;error &amp;amp;&amp;amp; &amp;lt;/math&amp;gt;error -&amp;gt; code != MS_NOERR) {&lt;br /&gt;
  printf (&amp;quot;Error in &lt;br /&gt;
           &amp;lt;math&amp;gt;error -&amp;gt; routine, &amp;lt;/math&amp;gt;error -&amp;gt; message);&lt;br /&gt;
           &amp;lt;math&amp;gt;error = &amp;lt;/math&amp;gt;error -&amp;gt; next ();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst sollten Sie zu Beginn jedes Skriptes die Fehlerliste zurücksetzen; das passiert hier in der ersten Zeile.&lt;br /&gt;
&lt;br /&gt;
Danach holt man sich das globale Fehlerobjekt, über welches dann iteriert wird. Für jeden erzeugten Fehler wird dessen Eigenschaft =code=  abgefragt. Dieser Code ist eine aus einer Liste von Fehlerkonstanten. Falls es sich tatsächlich um einen Fehler handelt -- auch keine Fehler ist ein Fehler, allerdings einer vom Typ =MS_NOERR=  wird eine entsprechende Fehlermeldung ausgegeben. Danach wird zum nächsten unbearbeiteten Fehler in der Liste gesprungen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie nach der Abfrage des nächsten Fehlers keine Möglichkeit mehr haben, zu bereits abgearbeiteten Fehlern zurückzukehren.&lt;br /&gt;
&lt;br /&gt;
Sie finden alle Details zu =errorObj=  in der Referenz ab Seite~\pageref{ref:phpms:errorobj}. Die möglichen Fehlercodes sind außerdem Bestandteil von Tabelle~\ref{tab:ref:mapscript:const}, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt.&lt;br /&gt;
&lt;br /&gt;
==Die layerObj-Klasse==\index{Mapscript!layerObj}\index{layerObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt läßt Sie auf alle Bestandteile einer Layer-Sektion im Mapfile zugreifen.&lt;br /&gt;
&lt;br /&gt;
Dafür müssen Sie natürlich erst einmal wissen, welche Layer sich in einem gegebenen Mapfile befinden. Natürlich könnte man einfach alle Namen in seinem Script hartkodieren. Allerdings kommt man dann schnell in Bedrängnis, wenn sich am Mapfile etwas ändert. Außerdem läßt sich auf diese Weise keine Software schreiben, die sich mit beliebigen Mapfiles auseinandersetzt.&lt;br /&gt;
&lt;br /&gt;
Zuerst einmal können alle Layer in einem Mapfile durch einen Index angesprochen werden, der ihrer Position im Mapfile entspricht. Der erste Layer erhält dabei den Index =0= , der zweite den Index =1=  und so weiter\footnote{Informatiker beginnen immer bei Null mit dem Zählen, nicht bei Eins. Das liegt daran, dass sie sich bei Listen und so weiter nicht dafür interessieren, welche Position ein Element absolut besitzt, sondern welchen Abstand vom Beginn der Liste. Und der ist für das erste Element Null, und so weiter.}. Mit einer Schleife, die über die Anzahl der Layer läuft, kann man also beispielsweise folgendes machen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;num = &amp;lt;/math&amp;gt;map -&amp;gt; numlayers;&lt;br /&gt;
for (&amp;lt;math&amp;gt;i = 0; &amp;lt;/math&amp;gt;i &amp;lt; numlayers; &amp;lt;/math&amp;gt;i++) {&lt;br /&gt;
  &amp;lt;math&amp;gt;layer = &amp;lt;/math&amp;gt;map -&amp;gt; getlayer (&amp;lt;math&amp;gt;i);&lt;br /&gt;
  ... jetzt passieren Dinge mit &amp;lt;/math&amp;gt;layer ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man kann die Layer aber auch über Ihren Namen ansprechen. Dabei holt man sich zuerst alle Layer-Namen via =getAllLayerNames()=  aus dem mapObj (man erhält ein Array aller Namen zurück), und spricht dann die Layer einzeln mit =getLayerByName()=  an.&lt;br /&gt;
&lt;br /&gt;
Die häufigste Aktion mit einem Layer ist, Queries auszuführen, beziehungsweise danach Query-Ergebnisse aus ihm herauszuholen.&lt;br /&gt;
&lt;br /&gt;
===Queries auf Layer===&lt;br /&gt;
&lt;br /&gt;
Queries liefern seit Version~{3.5} des MapServers keine Objekte vom Type resultObj mehr direkt zurück. Vielmehr werden die Ergebnisse von Queries nun in den Layer-Objekte festgehalten.&lt;br /&gt;
&lt;br /&gt;
Damit Anfragen auf einen Layer gemacht werden können, muß dieser im Mapfile einen =TEMPLATE= -Eintrag besitzen. Dieser Eintrag kann durchaus leer sein. Alternativ zur Angabe auf Layer-Ebene kann =TEMPLATE=  auch nur in einigen (oder allen) =CLASS= es des Mapfiles stehen. Die Queries werden dann nur auf Mitglieder dieser Klasse angewendet.&lt;br /&gt;
&lt;br /&gt;
Am häufigsten werden Queries auf einem mapObj ausgeführt; alle Query-Funktionen lassen sich jedoch auch auf einzelne Layer anwenden. Werden Queries auf mapObj-Objekte angewendet, werden einfach alle in Frage kommenden Layer der Reihe nach mit  der entsprechenden Funktion bedacht.&lt;br /&gt;
&lt;br /&gt;
Queries können auf drei verschiedene Weisen ausgeführt werden: an bestimmten Punkten, mit Hilfe eines Rechtecks und, ganz neu, anhand beliebiger Shapes. Doch wir beginnen mit den Punkt-Queries.&lt;br /&gt;
&lt;br /&gt;
Betrachten Sie folgendes Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; setXY (300000, 500000);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; queryByPoint (&amp;lt;/math&amp;gt;punkt, MS_SINGLE, -1);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird zuerst ein Punkt-Objekt aus den Koordinaten gebaut, die abgefragt werden sollen. Für gewöhnlich kommen diese Koordinaten durch einen Mausklick auf ein Bild in einem Formular zustande. Beachten Sie bitte, dass dieser Punkt im =Koordinatensystem der Karte=  vorliegen muß; die Pixelwerte eines Mausklicks auf eine Karte müssen Sie also zuerst in passende Werte umrechnen.&lt;br /&gt;
&lt;br /&gt;
Danach wird auf dem gewünschten Layer eine Query durchgeführt. Dazu wird der Punkt übergeben, die Art der Anfrage (hier soll nur ein einzelnes Ergebnis erzeugt werden; mit =MS_MULTIPLE=  wären mehrere Ergebnisse möglich), und schließlich ein Puffer. Dieser Puffer ist ein Radius um den Abfragepunkt herum, in den Einheiten der Karte. Ein negativer Wert führt dazu, dass der im Mapfile gesetzte Wert verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Bevor man sich auf eventuelle Resultate stürzt, sollte man prüfen, ob es überhaupt Resultate gab -- die Anfrage kann schließlich auch ins Leere gegangen sein. Dazu prüft man den Rückgabewert der Funktion. Ist dieser =MS_SUCCESS= , so ist alles in Ordnung und man kann fortfahren. Trifft man auf =MS_FAILURE= , so gab es keine Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
Etwas problematisch ist, dass alle Query-Funktionen auch Fehlernachrichten produzieren, wann immer es keine Resultate gab. Dieses Verhalten läßt sich für einzelne Funktionen jedoch mit einem vorangestellten =@=  abstellen. Ein korrekterer Aufruf der obigen Funktion wäre also:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if ((&amp;lt;math&amp;gt;layer -&amp;gt; @queryByPoint (&amp;lt;/math&amp;gt;punkt, MS_SINGLE, -1))&lt;br /&gt;
                                          == MS_SUCCESS) {&lt;br /&gt;
  ... es gab Ergebnisse ...&lt;br /&gt;
} else {&lt;br /&gt;
  ... Fehlerbehandlung ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt können wir uns endlich mit dem Ergebnis des Mausklicks auseinandersetzen. Oder besser: mit den Ergebnissen, denn es können ja mehre sein. Mit =getnumresult()=  bringen wir die Anzahl der Resultate eines Layers in Erfahrung; haben wir nur ein Resultat, ist das nicht nötig. Dieses eine Resultat hat immer den Index =0= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;resultat = &amp;lt;/math&amp;gt;layer -&amp;gt; getResult (0);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;si = &amp;lt;/math&amp;gt;resultat -&amp;gt; shapeindex;&lt;br /&gt;
&amp;lt;math&amp;gt;ti = &amp;lt;/math&amp;gt;resultat -&amp;gt; tileindex;&lt;br /&gt;
&amp;lt;math&amp;gt;ti = &amp;lt;/math&amp;gt;resultat -&amp;gt; classindex;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat-Objekt besitzt also drei Eigenschaften: einen Shapeindex, der die Nummer des Shapes im Shapefile angibt, das dem Layer zugrunde liegt; einen Tileindex, der für gekachelte Shapefiles angibt, in welcher Kachel das Ergebnis aufgetreten ist; und schließlich einen Classindex, der die Class im Layer bezeichnet, für den das Ergebnis aufgetreten ist.&lt;br /&gt;
&lt;br /&gt;
Mit diesen Angaben können Sie dann verfahren, wie Sie es für richtig halten. Sie können zum Beispiel die Daten aus dem =.dbf= -File herausfischen, die dem Shape zugrunde liegen\footnote{Beachten Sie an dieser Stelle die eigenwillige Zählweise in =.dbf= -Dateien, die auch in PHP übernommen wurde: die Zeilen in einer solche Datei sind nicht bei 0 beginnend durchnummeriert, sondern bei 1}. Sie könnten beispielsweise auch auf das gesuchte Shape heranzoomen, indem Sie anhand des gefundenen Index die Bounding Box des Shapes aus dem Shapefile auslesen (siehe auch shapefileObj weiter unten) und diese Bounding Box als neue Extents für die Karte setzen.&lt;br /&gt;
&lt;br /&gt;
Von den einfachen Punkt-Queries kann man nun voranschreiten zu den Anfragen, die über ein Rechteck definiert sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; queryByRect (&amp;lt;/math&amp;gt;rechteck);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Rechteck ist dabei ein rectObj, wie es weiter unten im Text besprochen wird. Die restliche Vorgehensweise entspricht exakt demjenigen bei Punktabfragen.&lt;br /&gt;
&lt;br /&gt;
Hinweise: Rechtecke lassen sich in &amp;quot;`normalem&amp;quot;' HTML nicht erzeugen. Mit JavaScript oder dem ROSA-Applet sieht das schon wieder anders aus. Beachten Sie aber, dass insbesondere öffentliche Institutionen unter Umständen äußerst restriktive Bestimmungen haben, was den Einsatz von JavaScript, dynamischem HTML, Java und so weiter angeht. Auch sicherheitsbewußte Privatanwender haben JavaScript erst gar nicht aktiviert. Überdenken Sie den Einsatz dieser Technologien.&lt;br /&gt;
&lt;br /&gt;
Das gilt auch für die folgende Weise, Queries zu stellen, nämlich anhand eines Shapes, also eines beliebigen Polygons:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;layer -&amp;gt; queryByShape (&amp;lt;/math&amp;gt;shape);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Art der Query entfaltet Ihren Nutzen weniger anhand von Punkten, die in einem Web-Interface ausgewählt werden können, als vielmehr beim Vergleich von Shapes mit Shapes aus einem anderen Shapefile: wenn Sie beispielsweise ein Shapefile mit Bundesländern haben und eines, indem ohne eine solche Referenzierung Angaben von Verkaufszahlen gespeichert sind, dann lassen sich durch den 'Verschnitt' beider Daten aussagekräftige Ergebnisse erzeugen.&lt;br /&gt;
&lt;br /&gt;
Wie man mit MapScript einzelne Shapes aus einem Shapefile extrahiert erfahren Sie weiter unten bei der Besprechung von shapefileObj. Ein schneller Weg involviert allerdings die Methode =getShape()= , die bereits auf der Ebene des Layers vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Eigenschaften und Methoden}&lt;br /&gt;
&lt;br /&gt;
Die weiteren Funktionen in layerObj dienen im wesentlichen dazu, Zugriff auf die einzelnen Werte eines Layers zu erhalten, beziehungsweise auf die weiteren Objekte darin bezug nehmen zu können, insbesondere auf die Classes im Layer.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Methoden und Eigenschaften, die layerObj bietet, sind im Anhang ab Seite~\ref{ref:phpms:layerobj} aufgelistet.&lt;br /&gt;
&lt;br /&gt;
==Die classObj-Klasse==\index{Mapscript!classObj}\index{classObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt entspricht einer Class innerhalb eines Layers. Mit einem classObj können Sie im wesentlichen Farben und Symbole für eine Class setzen -- insbesondere aber die Expressions für eine Class.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel, wie man das verwenden kann: Nehmen wir an, Sie haben einen Datenbestand, der Ihnen die Deutschland in lauter kleine Gebiete einteilt. In der dazu gehörigen ''.dbf'' -Datei haben Sie in einer Spalte für jedes Gebiet den prozentualen Anteil an Waldfläche gespeichert. Diese Spalte trägt den Namen =WALD= .&lt;br /&gt;
&lt;br /&gt;
In Ihrer Applikation haben Sie nun ein Eingabefeld, das es dem Benutzer ermöglicht, eine Anzahl von Grün-Abstufungen zu bestimmen, in die der Layer eingeteilt werden soll. Gibt der Benutzer beispielsweise =4=  ein, werden dem Layer vier Klassen hinzugefügt, die von grün bis weiß vier Farbstufen annehmen.&lt;br /&gt;
&lt;br /&gt;
Sie errechnen in der PHP-Seite dann die Unterteilung in vier Grünstufen und setzen vier verschiedene Classes.&lt;br /&gt;
&lt;br /&gt;
==Die imageObj-Klasse==\index{Mapscript!imageObj}\index{imageObj}&lt;br /&gt;
&lt;br /&gt;
Diese Objekte werden niemals 'von Hand' erzeugt, sondern immer nur durch den Aufruf von Methoden anderer MapScript-Objekte. Bei diesen Image-Objekten handelt es sich nicht um Bild-Dateien, sondern lediglich um die Bilddaten, die in einem Puffer im Speicher liegen und noch darauf warten, gespeichert zu werden.&lt;br /&gt;
&lt;br /&gt;
Alle =draw= -Methoden von mapObj erzeugen ein imageObj. Am häufigsten wird danach die Methode =saveWebImage()=  aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;image = &amp;lt;/math&amp;gt;map -&amp;gt; draw ();&lt;br /&gt;
&amp;lt;math&amp;gt;url = &amp;lt;/math&amp;gt;image -&amp;gt; saveWebImage (MS_JPEG, 0, 0, 90);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter der Methode ist das gewünschte Bildformat, das meistens =MS_PNG=  sein wird, ab und zu =MS_JPEG=  und nur, wenn es sich nicht vermeiden läßt, =MS_GIF= .&lt;br /&gt;
&lt;br /&gt;
Die beiden folgenden Parameter legen eine Transparenz der Hintergrundfarbe bzw. ein Interlacing für das Bild fest. Der letzte (optionale) Parameter legt für Bildformate, die eine Kompression zur Verfügung stellen, den Grad dieser Kompression fest. Werte zwischen 0 und 100 sind hier möglich.&lt;br /&gt;
&lt;br /&gt;
Eine vollständige Aufzählung aller Methoden dieses Objektes finden Sie im Anhang ab Seite~\pageref{ref:phpms:imageobj}.&lt;br /&gt;
&lt;br /&gt;
==Die labelObj-Klasse==\index{Mapscript!labelObj}\index{labelObj}&lt;br /&gt;
&lt;br /&gt;
Labels befinden sich innerhalb von classObj-Objekten. Diese Klasse kennt erstaunlicherweise keine einzige Methode außer =set()= , dafür eine große Menge von Eigenschaften. In der Referenz finden Sie ab Seite~\pageref{ref:phpms:labelobj} eine ausführliche Aufzählung.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet übrigens auch, dass es keinen Konstruktor für diese Klasse gibt und demnach keine Möglichkeit, ein labelObj 'von Hand' zu erstellen.&lt;br /&gt;
&lt;br /&gt;
==Die webObj-Klasse==\index{Mapscript!webObj}\index{webObj}&lt;br /&gt;
&lt;br /&gt;
Ebenso wie beim labelObj gibt es auch für diese Klasse keinen Konstruktor und keine weiteren Methoden neben der =set()= -Methode. In der Referenz im Anhang finden Sie ab Seite~\pageref{ref:phpms:webobj} eine Liste aller Eigenschaften dieser Klasse.&lt;br /&gt;
&lt;br /&gt;
webObj-Objekte finden Sie immer als Bestandteil eines mapObj.&lt;br /&gt;
&lt;br /&gt;
==Die referenceMapObj-Klasse==\index{Mapscript!referenceMapObj}\index{referenceMapObj}&lt;br /&gt;
&lt;br /&gt;
Auch Objekte dieser Klasse kommen nur innerhalb eines mapObj vor, es gibt keinen Konstruktor und keine Methode außerhalb von =set()= .&lt;br /&gt;
&lt;br /&gt;
In der Referenz ab Seite~\pageref{ref:phpms:referencemapobj} finden Sie eine Liste aller Eigenschaften dieser Klasse.&lt;br /&gt;
&lt;br /&gt;
==Die colorObj-Klasse==\index{Mapscript!colorObj}\index{colorObj}&lt;br /&gt;
&lt;br /&gt;
Jede Karte verfügt über eine bestimmte Farbpalette. Diese Palette wird beim Generieren der Karte erstellt.&lt;br /&gt;
&lt;br /&gt;
Neue Farben lassen sich der Palette hinzufügen, indem man Objekte der Klasse colorObj erzeugt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;weiss = ms_newColorObj ();&lt;br /&gt;
&amp;lt;/math&amp;gt;weiss -&amp;gt; setRGB (255, 255, 255);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Farbe kann dann an den Stellen, wo es möglich und nötig ist, verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==Die pointObj-Klasse==\index{Mapscript!pointObj}\index{pointObj}&lt;br /&gt;
&lt;br /&gt;
Punkte werden an diversen Stellen in MapScript für verschiedene Dinge benötigt. Wann immer eine Funktion die zwei Koordinaten eines Punktes übergeben bekommt, wird ein pointObj verlangt. Sehen Sie sich beispielsweise die Verwendung von =queryByPoint=  im Abschnitt über das Objekt =layerObj=  an.&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt besitzt aber noch einige andere Methoden in MapScript. Insbesondere kann man damit die Abstände von Punkten zu anderen Punkten, zu Linien und zu Polygonen bestimmen; außerdem lassen sich einzelne Punkte mithilfe von Objekten der Klasse projectionObj projizieren. Des weiteren kann man einzelne Punkte aus Linien-Objekten extrahieren (siehe lineObj).&lt;br /&gt;
&lt;br /&gt;
pointObj gehört zu den Klassen, deren Speicher nach Gebrauch explizit freigegeben werden muß (siehe Seite~\pageref{text:mapscript:memory}).&lt;br /&gt;
&lt;br /&gt;
Die Referenz zu allen Methoden von pointObj finden Sie auf Seite~\pageref{ref:phpms:pointobj}.&lt;br /&gt;
&lt;br /&gt;
==Die lineObj-Klasse==\index{Mapscript!lineObj}\index{lineObj}&lt;br /&gt;
&lt;br /&gt;
Linien lassen sich entweder von Hand konstruieren (indem man der Reihe nach einzelne Punkte hinzufügt), oder aber aus Shapes der Klasse shapeObj extrahieren. Außerdem lassen sich Linien natürlich ebenfalls projizieren.&lt;br /&gt;
&lt;br /&gt;
lineObj gehört zu den Klassen, deren Speicher nach Gebrauch explizit freigegeben werden muß (siehe Seite~\pageref{text:mapscript:memory}).&lt;br /&gt;
&lt;br /&gt;
Die Referenz zu allen Methoden von lineObj finden Sie auf Seite~\pageref{ref:phpms:lineobj}.&lt;br /&gt;
&lt;br /&gt;
==Die projectionObj-Klasse==\index{Mapscript!projectionObj}\index{projectionObj}&lt;br /&gt;
&lt;br /&gt;
Dieses Objekt beschreibt einen Projektions-Abschnitt in einem Mapfile. Aber es kann auch jenseits von Mapfiles verwendet werden, um einzelne Punktkoordinaten umzuprojizieren.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel projiziert einen einzelnen Punkt von einer Längen-/Breitenangabe in einen Punkt im UTM 32-System:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;projin = ms_newProjectionObj (&amp;quot;proj=latlong&amp;quot;);&lt;br /&gt;
&amp;lt;/math&amp;gt;projout = ms_newProjectionObj (&amp;quot;proj=utm,zone=32,ellps=WGS84,&lt;br /&gt;
                                 datum=WGS84,no_defs&amp;quot;);&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; setXY (32.0, 51.0);&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = &amp;lt;/math&amp;gt;punkt -&amp;gt; project ();&lt;br /&gt;
printf (&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die genauen Parameter, die Sie für die von Ihnen gewünschte Projektion verwenden müssen, finden Sie in der Dokumentation der Projektionsbibliothek proj.4.&lt;br /&gt;
&lt;br /&gt;
==Die shapefileObj-Klasse==\index{Mapscript!shapefileObj}\index{shapefileObj}&lt;br /&gt;
&lt;br /&gt;
Diese Klasse dient dazu, Shapefiles direkt manipulieren zu können. Sie können ein Shapefile als Objekt öffnen, einzelne Shapes referenzieren, die Eigenschaften des Shapefiles auslesen und sogar neue Shapes an das Shapefile anhängen und ganz neue Shapfiles erschaffen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass Sie kein mapObj erzeugen müssen, um Shapefiles auf diese Weise zu bearbeiten. Das shapefileObj ist unabhängig von den MapServer-verwandten Klassen in MapScript, kann aber natürlich mit diesen zusammen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Referenz für alle Eigenschaften und Methoden von shapefileObj finden Sie ab Seite~\ref{ref:phpms:shapefileobj}.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel gibt eine simple Statistik über alle Shapefiles aus, die es im aktuellen Verzeichnis finden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
foreach (glob (&amp;quot;*.shp&amp;quot;) as &amp;lt;math&amp;gt;shpfname) {&lt;br /&gt;
  &amp;lt;math&amp;gt;shpf = ms_newShapefileObj (&amp;lt;/math&amp;gt;shpfname, -1);&lt;br /&gt;
  &amp;lt;math&amp;gt;noshapes = &amp;lt;/math&amp;gt;shpf -&amp;gt; numshapes;&lt;br /&gt;
  &amp;lt;math&amp;gt;shpftype = &amp;lt;/math&amp;gt;shpf -&amp;gt; type;&lt;br /&gt;
  &amp;lt;math&amp;gt;bounds = &amp;lt;/math&amp;gt;shpf -&amp;gt; bounds;&lt;br /&gt;
&lt;br /&gt;
  printf (&amp;quot;Anzahl der Shapes: &lt;br /&gt;
          &amp;quot;Typ des Shapefiles: &lt;br /&gt;
          &amp;quot;Extents: &lt;br /&gt;
          &amp;lt;math&amp;gt;noshapes, &amp;lt;/math&amp;gt;shpftype,&lt;br /&gt;
          &amp;lt;math&amp;gt;bounds -&amp;gt; minx, &amp;lt;/math&amp;gt;bounds -&amp;gt; miny,&lt;br /&gt;
          &amp;lt;math&amp;gt;bounds -&amp;gt; maxx, &amp;lt;/math&amp;gt;bounds -&amp;gt; maxy);&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/math&amp;gt;shpf -&amp;gt; free ();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Struktur von PHP MapScript-Seiten==&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit PHP MapScript das Verhalten einer 'normalen' MapServer-Applikation nachbilden möchten, kann Ihnen das folgende Schema einige Anhaltspunkte geben, wie beim Aufbau einer solchen Applikation vorgegangen werden kann.&lt;br /&gt;
&lt;br /&gt;
Weitere Optionen für Ihre Applikation müssen an sinnvollen Stellen in das Gerüst eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
Diese Anleitung ist natürlich kein in Stein gemeißeltes Gesetz, sondern kann von Fall zu Fall abgeändert werden. Es bietet aber eine gute Orientierungshilfe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#Prüfen der übergebenen Parameter auf sinnvolle Werte&lt;br /&gt;
#Laden des Mapfiles&lt;br /&gt;
#Fallunterscheidung nach gewünschtem Modus:&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	##Simples Browsen (Pan) der Karte:&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Koordinaten des Mausklicks  		##&lt;br /&gt;
*Zoomen auf den Punkt mit einer Zoomtiefe von 1  		&lt;br /&gt;
	##Zoomen auf/um den betreffenden Punkt&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Koordinaten des Mausklicks  		##&lt;br /&gt;
*Zoomen auf den Punkt mit dem übergebenen Zoomfaktor  		&lt;br /&gt;
	##Zoomen auf das angeklickte Shape&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Shapenummer mittels queryByPoint  		##&lt;br /&gt;
*Öffnen des entsprechenden Shapefiles und Ermitteln der Extents des angeklickten Shapes  		##&lt;br /&gt;
*Zoomen auf das Shape mittels zoomByRect  		&lt;br /&gt;
	##Query auf den geklickten Punkt&lt;br /&gt;
		   		##&lt;br /&gt;
*Ermitteln der Kartenkoordinaten des angeklickten Punktes (oder mehrerer Punkte, falls es ein queryByRect ist)  		##&lt;br /&gt;
*Ausführen der Query  		##&lt;br /&gt;
*Auslesen des Ergebnis' (oder der Ergebnisse) aus einem oder mehreren Layer-Objekten  		##&lt;br /&gt;
*Präsentation der Ergebnisse  		&lt;br /&gt;
	&lt;br /&gt;
#Rendern der Karte und Abspeichern in einer Datei&lt;br /&gt;
#Eintragen des URL des fertigen Bildes in den entsprechenden HTML-Tag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Speichern von Map-Objekten in PHP-Sessions==&lt;br /&gt;
&lt;br /&gt;
Leider können Objekte aus PHP-MapScript (insbesondere ein mapObj) nicht in Sessions gespeichert werden. Der Grund dafür ist, dass die Objekte in PHP-MapScript keine 'reinen' PHP-Objekte sind, sondern lediglich als Wrapper um die C-Daten\-struk\-turen des MapServer-Quellcodes angelegt sind. Das führt dazu, dass beim Speichern in einer Sitzungsvariablen lediglich der Wrapper gespeichert wird, nicht aber das darunter liegende Objekt.&lt;br /&gt;
&lt;br /&gt;
Man muß also entweder (um beim Beispiel eines mapObj zu beiben) die ''vorgenommenen Änderungen''  auf eine genehme Art und Weise speichern und mitschleifen, um diese dann jedesmal auf ein neu erstelltes mapObj anzuwenden; oder man speichert die fertige Karte als Datei im System ab und speichert den Dateinamen der Karte in der Sitzungsvariablen.&lt;br /&gt;
&lt;br /&gt;
==Speicherverwaltung mit MapScript==(4)&lt;br /&gt;
&lt;br /&gt;
Die Speicherverwaltung aller MapScript-Objekte, die im Zusammenhang mit dem Mapfile stehen, geschieht automatisch. Sie müssen also nicht für jedes Objekt Speicher anfordern und wieder freigeben.&lt;br /&gt;
&lt;br /&gt;
Etwas anders verhält es sich bei Objekten zu Shapefiles und allen geometrischen Objekten wie Punkten, Linien und so weiter. Das Anfordern von Speicher entfällt zwar. Allerdings sollten alle Objekte dieser am Ende (also nachdem man Gebrauch von ihnen gemacht hat und sie nicht mehr benötigt) explizit zerstört und alle verwendeten Resourcen freigegeben werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;punkt = ms_newPointObj ();&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/math&amp;gt;punkt -&amp;gt; free ();&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwar wird jeder Speicher, der innerhalb eines PHP-Skriptes benutzt wird, nach dem Abarbeiten der Seite automatisch wieder freigegeben. Allerdings kann bei beim exzessiven Gebrauch von Objekten innerhalb einer Seite vielleicht in Speicherschwierigkeiten kommen.&lt;br /&gt;
&lt;br /&gt;
Außerdem können Sie in Ihrem Programm zwar keine Probleme mit dem Speicher haben. Denken Sie aber immer daran, dass Kollegen, Freunde, Mitarbeiter und so weiter später vielleicht auf die Idee kommen können, das Programm abzuändern und zu erweitern. Wenn Sie von vornherein vernünftig mit dem Speicher umgegangen sind, so sind Sie auf der sicheren Seite. Es zeugt darüber hinaus von einem sauberen Programmierstil.&lt;br /&gt;
&lt;br /&gt;
=Weitere Sprachen=&lt;br /&gt;
&lt;br /&gt;
MapScript kann mit verschiedenen Sprachen genutzt werden. Neben PHP sind die populärsten Perl, Java und Python.&lt;br /&gt;
&lt;br /&gt;
Die MapServer-Entwickler bedienen sich bei diesen Sprachen des Interface-Generators SWIG~[[http:website:swig]]. Die Verwendung von SWIG und die Erstellung von MapScript-Modulen für andere Programmiersprachen wird im Anhang besprochen.&lt;br /&gt;
&lt;br /&gt;
==Perl==&lt;br /&gt;
&lt;br /&gt;
Zu Perl gibt es unglaublich viel Literatur. Nichts falsch machen kann man wohl mit~[[wall:1996:perl5]], dem berühmten Camel Book. Es ist auch auf deutsch erschienen.&lt;br /&gt;
&lt;br /&gt;
==Java==&lt;br /&gt;
&lt;br /&gt;
Java ist eine Sprache, aus der ein unglaublicher Hype hervorgegangen ist. Die Literatur, die sich mit Java auseinandersetzt, ist dermaßen umfangreich, dass Sie sich von dem Buchhändler Ihres Vertrauens beraten lassen sollten.&lt;br /&gt;
&lt;br /&gt;
==Python==&lt;br /&gt;
&lt;br /&gt;
Python hat sich einen Namen als einfache, strukturierte und schnell zu lernende Programmiersprache gemacht. Wer des Englischen mächtig ist, ist mit der Lektüre von~[[lutz:1999:python]] recht gut beraten; das Buch ist auch auf deutsch erschienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Java-Applets}\index{Applets}(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Mapplet=\index{Mapplet}(2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=ROSA=(3)\index{ROSA}&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_5&amp;diff=34429</id>
		<title>HBUMNMapServer ger Capter 5</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_5&amp;diff=34429"/>
		<updated>2009-01-23T10:12:30Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Demos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Demos =&lt;br /&gt;
\index{Demos}(1)&lt;br /&gt;
&lt;br /&gt;
Um einen ersten Eindruck vom MapServer zu bekommen, gibt es Demo-Applikationen. Eine nicht unerhebliche Anzahl von Anfragen auf der Mailingliste bezieht sich auf das Einrichten der Demos; es scheint also nicht ganz trivial zu sein.&lt;br /&gt;
&lt;br /&gt;
Um einen reibungslosen Einstieg zu erleichtern, gebe ich hier -- soweit möglich -- eine Schritt-für-Schritt-Anleitung, damit Sie die Demos so schnell wie möglich ausprobieren können. Im wesentlichen handelt es sich um kleine Eingriffe in die Mapfiles bzw. die Templates der Anwendung, also Dinge, die sich mit einem beliebigen Texteditor schnell und einfach erledigen lassen.&lt;br /&gt;
&lt;br /&gt;
Es wird aber davon ausgegangen, dass Sie bereits eine laufende MapServer-Installation haben; dass Sie also das Binary in das entsprechende =cgi-bin= -Verzeichnis im Webserver kopiert haben, und dass ein Aufruf wie in Abschnitt~\ref{text:mapfile:cgi} beschrieben, die zu erwartende Fehlermeldung produziert.&lt;br /&gt;
&lt;br /&gt;
=Itasca=\index{Itasca}\index{Demos!Itasca}(2)&lt;br /&gt;
&lt;br /&gt;
Itasca County ist Teil des Bundesstaates Minnesota, hat etwa 43000 Einwohner, die in 16 Städten und 42 Townships leben, und muß vor allen Dingen seit Urzeiten als typisches Demo für den MapServer herhalten. Sie können es als Paket von der MapServer-Website herunterladen. Lassen Sie sich dabei vom Dateinamen =itasca3.5.tar.gz=  nicht irritieren, diese Fassung ist für MapServer 4.0 immer noch aktuell.&lt;br /&gt;
&lt;br /&gt;
Die Schritte, die nun zu unternehmen sind, sind die folgenden:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#Archiv entpacken&lt;br /&gt;
#Temporäres Verzeichnis anlegen&lt;br /&gt;
#Zugriffsrechte anpassen&lt;br /&gt;
#Initialisierungsseite editieren&lt;br /&gt;
#Konvertieren der GIF-Symbole (optional)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Entpacken und Verzeichnisse setzen}&lt;br /&gt;
&lt;br /&gt;
Entpacken Sie die das Archiv in das =htdocs= -Verzeichnis Ihres Webservers, unter Linux beispielsweise so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # tar -xzvf itasca3.5.tar.gz&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Legen Sie nun, ebenfalls im =htdocs= -Verzeichnis, ein Unterverzeichnis =ms_tmp=  an. Dieses Verzeichnis wird von MapServer dazu benutzt werden, um die erzeugten Bilder zwischenzuspeichern.&lt;br /&gt;
&lt;br /&gt;
Nun sollten die Zugriffs- bzw. Besitzrechte korrekt gesetzt werden. Die Demo-Dateien sollten auf den meisten Systemen dem Benutzer =root=  gehören, während das Verzeichnis für die temporären Dateien von dem Benutzer beschreibbar sein muß, unter dem der Webserver läuft. Unter Debian Linux ist das beispielsweise =www-data= . Das Setzen der Rechte könnte also zum Beispiel so aussehen:&lt;br /&gt;
&lt;br /&gt;
(3)&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # chown -R root.root itasca/&lt;br /&gt;
 # chown www-data.root itasca/&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Dateien editieren}&lt;br /&gt;
&lt;br /&gt;
Die restliche Arbeit besteht nun darin, die Startseite des Demos anzupassen. Dazu müssen Sie die Dateien jeweils in einem Texteditor Ihrer Wahl öffnen. Unter Windows könnte das beispielsweise =notepad=  sein, unter Linux emacs oder vim.&lt;br /&gt;
&lt;br /&gt;
Öffnen Sie zuerst die Startseite des Demos mit dem Namen =demo_init.html= . Die Zeilen, die Sie wahrscheinlich anpassen möchten, sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=&amp;lt;form method=GET action=&amp;quot;{= /cgi-bin/mapserv&amp;quot;{}&amp;gt;}\\ Hier setzen Sie das zu verwendende MapServer-Binary. Dieser Eintrag stimmt höchstwahrscheinlich schon.  &lt;br /&gt;
*=&amp;lt;input type=&amp;quot;{= hidden&amp;quot;{} name=&amp;quot;{}map&amp;quot;{} value=&amp;quot;{}...&amp;quot;{}&amp;gt;}\\ Wo hier die drei Punkte gesetzt sind, geben Sie den vollständigen Pfad zum Mapfile an. Unter Windows beinhaltet das die Angabe des Laufwerks, also zum Beispiel =c:= .  &lt;br /&gt;
*=&amp;lt;input type=&amp;quot;{= hidden&amp;quot;{} name=&amp;quot;{}program&amp;quot;{} value=&amp;quot;{}/cgi-bin/mapserv&amp;quot;{}&amp;gt;}\\ Hier setzen Sie noch einmal den gleichen Wert wie beim ersten Punkt in dieser Aufzählung. Ist in den meisten Fällen bereits korrekt.  &lt;br /&gt;
*=&amp;lt;input type=&amp;quot;{= hidden&amp;quot;{} name=&amp;quot;map_web_imagepath&amp;quot;{} value=&amp;quot;{}...&amp;quot;{}&amp;gt;}\\ Wo hier die drei Puntke gesetzt sind, geben Sie den vollständigen Pfad zum temporären Verzeichnis an, dass Sie weiter oben erzeugt haben.  &lt;br /&gt;
*=&amp;lt;input type=&amp;quot;{= hidden&amp;quot;{} name=&amp;quot;{}map_web_imageurl&amp;quot;{} value=&amp;quot;{}/ms_tmp/&amp;quot;{}&amp;gt;}\\ Hier geben Sie den URL des temporären Verzeichnisses an. Wenn Sie das Verzeichnis wie oben beschrieben in =htdocs=  angelegt haben, reicht hier =/ms_tmp/=  aus.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{GIF-Symbole konvertieren}&lt;br /&gt;
&lt;br /&gt;
Dieser Schritt ist optional. Er muß nur dann unternommen werden, wenn Ihr MapServer keine GIF-Unterstützung beinhaltet. Wenn Sie vorkompilierte Binaries unter Windows benutzen, haben Sie GIF-Unterstützung und können diesen Schritt auslassen. Sobald Sie aber aktuellen Quellcode beispielsweise unter Linux selber kompiliert haben, müssen Sie die GIF-Symbole konvertieren und sie in das Mapfile aufnehmen.&lt;br /&gt;
&lt;br /&gt;
Am schnellsten geht die Konvertierung mit dem Werkzeug ''ImageMagick'' ~[[http:website:imagemagick]], das heutzutage jeder Linux-Distribution beiliegt und auch für Windows zu haben ist.&lt;br /&gt;
&lt;br /&gt;
Wechseln Sie in das Verzeichnis =symbols=  des Demos und führen dort folgendes aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # mogrify -type png *.gif&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Referenzkarte im Unterverzeichnis =graphics=  muß auf die gleiche Weise konvertiert werden.&lt;br /&gt;
&lt;br /&gt;
Nun müssen im Mapfile noch alle Verweise auf GIF-Symbole geändert werden. Das können Sie natürlich von Hand machen, oder mit der Funktion 'Suchen und Ersetzen' in Ihrem Editor. Es kann unter Linux aber beispielsweise auch so geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # sed -e 's/gif/png/' demo.map &amp;gt; tmp~ &amp;amp;&amp;amp; mv tmp~ demo.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=GMap=\index{GMap}\index{Demos!GMap}(4)&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{gmap}{Das kanadische GMap-Demo}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Dieses Demo stammt von der kanadischen Firma DM Solutions, die einen erheblichen Einfluß auf die Entwicklung des MapServers hat. Von ihrer Website~[[http:website:dmsolutions]] läßt sich ein Paket mit dem Namen =gmap-ms3.6.tar.gz=  herunterladen. Stören Sie sich nicht an der Versionsnummer; das ganze funktioniert hervorragend mit MapServer 4.0.&lt;br /&gt;
&lt;br /&gt;
Für GMap muß PHP MapScript installiert sein. Dieser Vorgang wird hier nicht detailliert beschrieben, das passiert allerdings im Anhang ab Seite~\pageref{anhang:compile:mapscript:php}. Einen Screenshot des funktionierenden Demos können Sie in Abbildung~\ref{gmap}.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Schritte müssen Sie für das korrekte Funktionieren des Demos unternehmen:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#Auspacken des Archivs&lt;br /&gt;
#Zugriffsrechte setzen&lt;br /&gt;
#Anpassen der PHP-Seite(n)&lt;br /&gt;
#Konvertieren der GIF-Symbole (optional)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Entpacken und Zugriffsrechte}&lt;br /&gt;
&lt;br /&gt;
Begeben Sie sich in das =htdocs= -Verzeichnis Ihres Webservers und entpacken Sie das Archiv, unter Linux beispielsweise folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # tar -xzf gmap-ms3.6.tar.gz&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Passen Sie dann noch die Besitzrechte für das neue Verzeichnis an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # chown -R root.root gmap/&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Anpassen der PHP-Seiten}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Änderungen werden, wie schon beim Itasca-Demo, ganz einfach mit einem Texteditor vorgenommen.&lt;br /&gt;
&lt;br /&gt;
Zu Beginn der Datei =gmap75.phtml=  finden Sie Zeilen, die prüfen, auf welchen Betriebssystem es sich befindet und in Abhängigkeit davon die MapScript-Bibliothek lädt. Unter Windows ist das eine Datei mit der Endung =.dll= , unter Linux mit der Endung =.so= . Wenn Sie beim Aufruf von&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://name.des.servers/gmap/htdocs/gmap75.phmtml&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
eine Fehlermeldung erhalten, dass MapScript nicht geladen werden konnte, ändern Sie den Namen der Bibliothek in den korrekten Wert. Beispielsweise wird es auf vielen Unix-Systemen passieren, dass die Zeilen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (!extension_loaded(&amp;quot;MapScript&amp;quot;))&lt;br /&gt;
     dl(&amp;quot;php_mapscript_36.so&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
geändert werden müssen in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (!extension_loaded(&amp;quot;MapScript&amp;quot;))&lt;br /&gt;
     dl(&amp;quot;php_mapscript.so&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist insbesondere der Fall, wenn Sie aus den Quellen selberkompiliert haben, da die Datei dann nicht so heißt, wie von GMap ursprünglich erwartet. &lt;br /&gt;
&lt;br /&gt;
Als nächstes muß noch das Mapfile angepaßt werden. Falls Sie den Schritten für das Itasca-Demo weiter oben gefolgt sind, und das Verzeichnis für temporäre Pfade wie auf Seite~\pageref{text:demos:itasca:temp} beschrieben anglegt haben, müssen Sie in =gmap75.map=  die Zeile für den =IMAGEPATH=  geändert werden; dort steht dann&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 IMAGEPATH &amp;quot;/.../ms_tmp/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wobei die drei Punkte für den kompletten Pfad zum temporären Verzeichnis im System stehen und dementsprechend von Ihnen ausgefüllt werden müssen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Konvertierung der GIF-Symbole}&lt;br /&gt;
&lt;br /&gt;
Falls Ihre MapServer-Installation nicht mit GIF-Dateien umgehen kann (siehe auch weiter vorne in der entsprechenden Sektion zum Itasca-Demo), müssen Sie noch die Referenzkarte =keymap.gif=  im Unterverzeichnis =htdocs/images=  in ein PNG-Bild konvertieren, und den Verweis auf das Bild im Mapfile abändern.&lt;br /&gt;
&lt;br /&gt;
Die Konvertierung kann wieder mit ImageMagick geschehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # convert keymap.gif keymap.png&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf die Referenzkarte im Mapfile heißt dann:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 REFERENCE&lt;br /&gt;
   IMAGE &amp;quot;images/keymap.png&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der Java-Modus}&lt;br /&gt;
&lt;br /&gt;
Sollten Sie nun immer noch kein Bild in Ihrem Browser zu sehen bekommen, liegt es daran, dass GMap grundsätzlich im Java-Modus startet, Sie aber kein Java-Plugin in Ihrem Browser installiert haben. In diesem Fall können Sie mit einem Klick auf das Java-Symbol in der linken unteren Ecke in den 'reinen' HTML-Modus schalten.&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_4&amp;diff=34428</id>
		<title>HBUMNMapServer ger Capter 4</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_4&amp;diff=34428"/>
		<updated>2009-01-23T10:10:00Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Beispiel: Einspielen des Itasca-Demos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Datenbankanbindungen =&lt;br /&gt;
\index{Datenbanken}(1)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
(2)&lt;br /&gt;
\index{Datenbank!PostgreSQL}&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Nach der Installtion von Postgresql und Postgis muss das DBMS für die Nutzeranmeldung konfiguriert werden. &lt;br /&gt;
Dazu wird dem Benutzer postgres ein Password vergeben. &lt;br /&gt;
Als Benutzer postgres folgendes ausführen:&lt;br /&gt;
 psql&lt;br /&gt;
 alter user postgres with password 'newpassword';&lt;br /&gt;
 createdb -E UTF8 postgisdb&lt;br /&gt;
 createlang plpgsql postgisdb&lt;br /&gt;
 psql -f /usr/share/postgresql-8.3-postgis/lwpostgis.sql -d postgisdb&lt;br /&gt;
 psql -f /usr/share/postgresql-8.3-postgis/spatial_ref_sys.sql -d postgisdb&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Vorbereiten einer Datenbank für PostGIS}&lt;br /&gt;
&lt;br /&gt;
Dieser Teil gehört zum Abschnitt über die Installation von PostGIS im Anhang.&lt;br /&gt;
&lt;br /&gt;
==Shapefiles in PostGIS laden==(3)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shp2pgsql shapefile.shp tabellenname dbname &amp;gt; shapefile.sql&lt;br /&gt;
 # psql -f shapefile.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Erstellen von Indizes}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
PostGIS verwendet sogenannte GiST-Indizes, was wundersamerweise für Generalized Search Trees steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CREATE INDEX [idxname] ON [tablename] USING GIST&lt;br /&gt;
              ([geofeld] GIST_GEOMETRY_OPS);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Danach ist es sinnvoll, ein =VACUUM=  auf der Datenbank durchzuführen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 VACUUM ANALYZE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CREATE INDEX [idxname] ON [tablename] (oid);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel: Einspielen des Itasca-Demos===&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
&lt;br /&gt;
 S2P=/usr/local/GIS/bin/shp2pgsql&lt;br /&gt;
 PROJ=26915&lt;br /&gt;
 DBNAME=spatialdata&lt;br /&gt;
 rm -rf output.sql&lt;br /&gt;
 for s in *.shp; do&lt;br /&gt;
   SHPFBASE=`echo &amp;lt;math&amp;gt;s | sed -e s/.shp//g`&lt;br /&gt;
   &amp;lt;math&amp;gt;{S2P} -s &amp;lt;/math&amp;gt;{PROJ} -d &amp;lt;math&amp;gt;{SHPFBASE}.shp itasca_&amp;lt;/math&amp;gt;{SHPFBASE} \&lt;br /&gt;
     &amp;lt;/math&amp;gt;{DBNAME} &amp;gt;&amp;gt; output.sql&lt;br /&gt;
   echo -e &amp;quot;\n&amp;quot; &amp;gt;&amp;gt; output.sql&lt;br /&gt;
   echo -e &amp;quot;CREATE INDEX idx_itasca_&amp;lt;math&amp;gt;{SHPFBASE} ON \&lt;br /&gt;
     itasca_&amp;lt;/math&amp;gt;{SHPFBASE} USING \&lt;br /&gt;
     GIST (the_geom GIST_GEOMETRY_OPS);\n&amp;quot; &amp;gt;&amp;gt; output.sql&lt;br /&gt;
   echo -e &amp;quot;CREATE INDEX oid_itasca_&amp;lt;math&amp;gt;{SHPFBASE} ON \&lt;br /&gt;
     itasca_&amp;lt;/math&amp;gt;{SHPFBASE} (oid);\n&amp;quot; &amp;gt;&amp;gt; output.sql&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Danach kann diese Datei wie  beschrieben z.B. mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # psgl -d spatialdata -f output.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in die Datenbank übernommen werden.&lt;br /&gt;
&lt;br /&gt;
==Notation in Layern==&lt;br /&gt;
&lt;br /&gt;
Die Notation von PostGIS-Layern unterscheidet sich nur geringfügig von 'normalen' Vektordatenlayern. Zuerst ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   TYPE &amp;quot;LINE&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE POSTGIS&lt;br /&gt;
   CONNECTION &amp;quot;user=postgisuser dbname=berlin host=192.168.27.13&amp;quot;&lt;br /&gt;
   DATA &amp;quot;the_geom from roads&amp;quot;&lt;br /&gt;
   FILTER &amp;quot;length &amp;gt;= 20&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==PostGIS außerhalb des MapServers==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME:vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Maplab}\index{Maplab}(1)&lt;br /&gt;
&lt;br /&gt;
TODO: vervollständigen!!1!&lt;br /&gt;
&lt;br /&gt;
=Mapedit=&lt;br /&gt;
&lt;br /&gt;
TODO: vervollständigen!!1!&lt;br /&gt;
&lt;br /&gt;
=Mapbrowser=&lt;br /&gt;
&lt;br /&gt;
TODO: vervollständigen!!1!&lt;br /&gt;
&lt;br /&gt;
=GMap Factory=&lt;br /&gt;
&lt;br /&gt;
TODO:mehr!1!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Chameleon}\index{Chameleon}(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Mapfile-Prototyping mit vingar}&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_4&amp;diff=34427</id>
		<title>HBUMNMapServer ger Capter 4</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_4&amp;diff=34427"/>
		<updated>2009-01-23T10:08:57Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* PostgreSQL und PostGIS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Datenbankanbindungen =&lt;br /&gt;
\index{Datenbanken}(1)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
(2)&lt;br /&gt;
\index{Datenbank!PostgreSQL}&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Nach der Installtion von Postgresql und Postgis muss das DBMS für die Nutzeranmeldung konfiguriert werden. &lt;br /&gt;
Dazu wird dem Benutzer postgres ein Password vergeben. &lt;br /&gt;
Als Benutzer postgres folgendes ausführen:&lt;br /&gt;
 psql&lt;br /&gt;
 alter user postgres with password 'newpassword';&lt;br /&gt;
 createdb -E UTF8 postgisdb&lt;br /&gt;
 createlang plpgsql postgisdb&lt;br /&gt;
 psql -f /usr/share/postgresql-8.3-postgis/lwpostgis.sql -d postgisdb&lt;br /&gt;
 psql -f /usr/share/postgresql-8.3-postgis/spatial_ref_sys.sql -d postgisdb&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Vorbereiten einer Datenbank für PostGIS}&lt;br /&gt;
&lt;br /&gt;
Dieser Teil gehört zum Abschnitt über die Installation von PostGIS im Anhang.&lt;br /&gt;
&lt;br /&gt;
==Shapefiles in PostGIS laden==(3)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # shp2pgsql shapefile.shp tabellenname dbname &amp;gt; shapefile.sql&lt;br /&gt;
 # psql -f shapefile.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Erstellen von Indizes}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
PostGIS verwendet sogenannte GiST-Indizes, was wundersamerweise für Generalized Search Trees steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CREATE INDEX [idxname] ON [tablename] USING GIST&lt;br /&gt;
              ([geofeld] GIST_GEOMETRY_OPS);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Danach ist es sinnvoll, ein =VACUUM=  auf der Datenbank durchzuführen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 VACUUM ANALYZE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CREATE INDEX [idxname] ON [tablename] (oid);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel: Einspielen des Itasca-Demos===&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
&lt;br /&gt;
 S2P=/usr/local/GIS/bin/shp2pgsql&lt;br /&gt;
 PROJ=26915&lt;br /&gt;
 DBNAME=spatialdata&lt;br /&gt;
&lt;br /&gt;
 rm -rf output.sql&lt;br /&gt;
&lt;br /&gt;
 for s in *.shp; do&lt;br /&gt;
   SHPFBASE=`echo &amp;lt;math&amp;gt;s | sed -e s/.shp//g`&lt;br /&gt;
   &amp;lt;math&amp;gt;{S2P} -s &amp;lt;/math&amp;gt;{PROJ} -d &amp;lt;math&amp;gt;{SHPFBASE}.shp itasca_&amp;lt;/math&amp;gt;{SHPFBASE} \&lt;br /&gt;
     &amp;lt;/math&amp;gt;{DBNAME} &amp;gt;&amp;gt; output.sql&lt;br /&gt;
   echo -e &amp;quot;\n&amp;quot; &amp;gt;&amp;gt; output.sql&lt;br /&gt;
   echo -e &amp;quot;CREATE INDEX idx_itasca_&amp;lt;math&amp;gt;{SHPFBASE} ON \&lt;br /&gt;
     itasca_&amp;lt;/math&amp;gt;{SHPFBASE} USING \&lt;br /&gt;
     GIST (the_geom GIST_GEOMETRY_OPS);\n&amp;quot; &amp;gt;&amp;gt; output.sql&lt;br /&gt;
   echo -e &amp;quot;CREATE INDEX oid_itasca_&amp;lt;math&amp;gt;{SHPFBASE} ON \&lt;br /&gt;
     itasca_&amp;lt;/math&amp;gt;{SHPFBASE} (oid);\n&amp;quot; &amp;gt;&amp;gt; output.sql&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Danach kann diese Datei wie  beschrieben z.B. mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # psgl -d spatialdata -f output.sql&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in die Datenbank übernommen werden.&lt;br /&gt;
&lt;br /&gt;
==Notation in Layern==&lt;br /&gt;
&lt;br /&gt;
Die Notation von PostGIS-Layern unterscheidet sich nur geringfügig von 'normalen' Vektordatenlayern. Zuerst ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   TYPE &amp;quot;LINE&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE POSTGIS&lt;br /&gt;
   CONNECTION &amp;quot;user=postgisuser dbname=berlin host=192.168.27.13&amp;quot;&lt;br /&gt;
   DATA &amp;quot;the_geom from roads&amp;quot;&lt;br /&gt;
   FILTER &amp;quot;length &amp;gt;= 20&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==PostGIS außerhalb des MapServers==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME:vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Maplab}\index{Maplab}(1)&lt;br /&gt;
&lt;br /&gt;
TODO: vervollständigen!!1!&lt;br /&gt;
&lt;br /&gt;
=Mapedit=&lt;br /&gt;
&lt;br /&gt;
TODO: vervollständigen!!1!&lt;br /&gt;
&lt;br /&gt;
=Mapbrowser=&lt;br /&gt;
&lt;br /&gt;
TODO: vervollständigen!!1!&lt;br /&gt;
&lt;br /&gt;
=GMap Factory=&lt;br /&gt;
&lt;br /&gt;
TODO:mehr!1!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Chameleon}\index{Chameleon}(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\chapter{Mapfile-Prototyping mit vingar}&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34424</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34424"/>
		<updated>2009-01-23T07:33:56Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Den Kontext verwenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
      ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
      &amp;amp; VERSION=1.1.0&lt;br /&gt;
      &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
      &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
      &amp;amp; SRS=EPSG:4326&lt;br /&gt;
      &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
      &amp;amp; WIDTH=500&lt;br /&gt;
      &amp;amp; HEIGHT=500&lt;br /&gt;
      &amp;amp; X=250&lt;br /&gt;
      &amp;amp; Y=250&lt;br /&gt;
      &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
 Layer 'countyboundary'&lt;br /&gt;
   Feature 26: &lt;br /&gt;
     AREA = '7577272785.15393'&lt;br /&gt;
     PERIMETER = '436617.07762'&lt;br /&gt;
     CTY_NAME = 'Itasca'&lt;br /&gt;
     COUN = '31'&lt;br /&gt;
     CTY_ABBR = 'ITAS'&lt;br /&gt;
     ISLAND = 'N'&lt;br /&gt;
     CTY_FIPS = '61'&lt;br /&gt;
     RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     ...&lt;br /&gt;
     &amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DUMP TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;msGMLOutput &lt;br /&gt;
  xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
  xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
  xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
   &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
     &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
     &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
     &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
     &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
     &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
     &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
       &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
           393234.393701,5207990.085063&lt;br /&gt;
           495769.579719,5305374.105135&lt;br /&gt;
         &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
       &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
     &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
     &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
         &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
           &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
             393865.671855,5300138.258409&lt;br /&gt;
             393869.171975,5300138.258374 &lt;br /&gt;
             394516.694141,5300137.439369 &lt;br /&gt;
             395522.728579,5300136.241770 &lt;br /&gt;
             [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE WMS&lt;br /&gt;
   CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
     &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
     &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
     &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
   ?SERVICE=WFS&lt;br /&gt;
   &amp;amp;REQUEST=getCapabilities&lt;br /&gt;
   &amp;amp;map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
   dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
   &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
   &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34423</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34423"/>
		<updated>2009-01-23T07:33:23Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* WFS Client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
      ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
      &amp;amp; VERSION=1.1.0&lt;br /&gt;
      &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
      &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
      &amp;amp; SRS=EPSG:4326&lt;br /&gt;
      &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
      &amp;amp; WIDTH=500&lt;br /&gt;
      &amp;amp; HEIGHT=500&lt;br /&gt;
      &amp;amp; X=250&lt;br /&gt;
      &amp;amp; Y=250&lt;br /&gt;
      &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
 Layer 'countyboundary'&lt;br /&gt;
   Feature 26: &lt;br /&gt;
     AREA = '7577272785.15393'&lt;br /&gt;
     PERIMETER = '436617.07762'&lt;br /&gt;
     CTY_NAME = 'Itasca'&lt;br /&gt;
     COUN = '31'&lt;br /&gt;
     CTY_ABBR = 'ITAS'&lt;br /&gt;
     ISLAND = 'N'&lt;br /&gt;
     CTY_FIPS = '61'&lt;br /&gt;
     RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     ...&lt;br /&gt;
     &amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DUMP TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;msGMLOutput &lt;br /&gt;
  xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
  xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
  xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
   &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
     &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
     &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
     &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
     &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
     &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
     &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
       &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
           393234.393701,5207990.085063&lt;br /&gt;
           495769.579719,5305374.105135&lt;br /&gt;
         &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
       &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
     &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
     &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
         &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
           &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
             393865.671855,5300138.258409&lt;br /&gt;
             393869.171975,5300138.258374 &lt;br /&gt;
             394516.694141,5300137.439369 &lt;br /&gt;
             395522.728579,5300136.241770 &lt;br /&gt;
             [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE WMS&lt;br /&gt;
   CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
     &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
     &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
     &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
   ?SERVICE=WFS&lt;br /&gt;
   &amp;amp;REQUEST=getCapabilities&lt;br /&gt;
   &amp;amp;map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
  dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
  &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
  &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34422</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34422"/>
		<updated>2009-01-23T07:32:58Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Aufruf \&amp;amp; Capabilities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
      ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
      &amp;amp; VERSION=1.1.0&lt;br /&gt;
      &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
      &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
      &amp;amp; SRS=EPSG:4326&lt;br /&gt;
      &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
      &amp;amp; WIDTH=500&lt;br /&gt;
      &amp;amp; HEIGHT=500&lt;br /&gt;
      &amp;amp; X=250&lt;br /&gt;
      &amp;amp; Y=250&lt;br /&gt;
      &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
 Layer 'countyboundary'&lt;br /&gt;
   Feature 26: &lt;br /&gt;
     AREA = '7577272785.15393'&lt;br /&gt;
     PERIMETER = '436617.07762'&lt;br /&gt;
     CTY_NAME = 'Itasca'&lt;br /&gt;
     COUN = '31'&lt;br /&gt;
     CTY_ABBR = 'ITAS'&lt;br /&gt;
     ISLAND = 'N'&lt;br /&gt;
     CTY_FIPS = '61'&lt;br /&gt;
     RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     ...&lt;br /&gt;
     &amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DUMP TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;msGMLOutput &lt;br /&gt;
  xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
  xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
  xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
   &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
     &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
     &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
     &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
     &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
     &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
     &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
       &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
           393234.393701,5207990.085063&lt;br /&gt;
           495769.579719,5305374.105135&lt;br /&gt;
         &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
       &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
     &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
     &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
         &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
           &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
             393865.671855,5300138.258409&lt;br /&gt;
             393869.171975,5300138.258374 &lt;br /&gt;
             394516.694141,5300137.439369 &lt;br /&gt;
             395522.728579,5300136.241770 &lt;br /&gt;
             [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE WMS&lt;br /&gt;
   CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
     &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
     &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
     &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
   ?SERVICE=WFS&lt;br /&gt;
   &amp;amp;REQUEST=getCapabilities&lt;br /&gt;
   &amp;amp;map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
  dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
  &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
  &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34421</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34421"/>
		<updated>2009-01-23T07:32:22Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Projektionen in WFS-Servern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
      ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
      &amp;amp; VERSION=1.1.0&lt;br /&gt;
      &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
      &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
      &amp;amp; SRS=EPSG:4326&lt;br /&gt;
      &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
      &amp;amp; WIDTH=500&lt;br /&gt;
      &amp;amp; HEIGHT=500&lt;br /&gt;
      &amp;amp; X=250&lt;br /&gt;
      &amp;amp; Y=250&lt;br /&gt;
      &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
 Layer 'countyboundary'&lt;br /&gt;
   Feature 26: &lt;br /&gt;
     AREA = '7577272785.15393'&lt;br /&gt;
     PERIMETER = '436617.07762'&lt;br /&gt;
     CTY_NAME = 'Itasca'&lt;br /&gt;
     COUN = '31'&lt;br /&gt;
     CTY_ABBR = 'ITAS'&lt;br /&gt;
     ISLAND = 'N'&lt;br /&gt;
     CTY_FIPS = '61'&lt;br /&gt;
     RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     ...&lt;br /&gt;
     &amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DUMP TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;msGMLOutput &lt;br /&gt;
  xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
  xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
  xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
   &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
     &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
     &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
     &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
     &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
     &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
     &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
       &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
           393234.393701,5207990.085063&lt;br /&gt;
           495769.579719,5305374.105135&lt;br /&gt;
         &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
       &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
     &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
     &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
         &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
           &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
             393865.671855,5300138.258409&lt;br /&gt;
             393869.171975,5300138.258374 &lt;br /&gt;
             394516.694141,5300137.439369 &lt;br /&gt;
             395522.728579,5300136.241770 &lt;br /&gt;
             [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE WMS&lt;br /&gt;
   CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
     &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
     &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
     &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? SERVICE=WFS&lt;br /&gt;
  &amp;amp; REQUEST=getCapabilities&lt;br /&gt;
  &amp;amp; map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
  dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
  &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
  &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34420</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34420"/>
		<updated>2009-01-23T07:29:22Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* getFeatureInfo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
      ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
      &amp;amp; VERSION=1.1.0&lt;br /&gt;
      &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
      &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
      &amp;amp; SRS=EPSG:4326&lt;br /&gt;
      &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
      &amp;amp; WIDTH=500&lt;br /&gt;
      &amp;amp; HEIGHT=500&lt;br /&gt;
      &amp;amp; X=250&lt;br /&gt;
      &amp;amp; Y=250&lt;br /&gt;
      &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
 Layer 'countyboundary'&lt;br /&gt;
   Feature 26: &lt;br /&gt;
     AREA = '7577272785.15393'&lt;br /&gt;
     PERIMETER = '436617.07762'&lt;br /&gt;
     CTY_NAME = 'Itasca'&lt;br /&gt;
     COUN = '31'&lt;br /&gt;
     CTY_ABBR = 'ITAS'&lt;br /&gt;
     ISLAND = 'N'&lt;br /&gt;
     CTY_FIPS = '61'&lt;br /&gt;
     RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     ...&lt;br /&gt;
     &amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DUMP TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;msGMLOutput &lt;br /&gt;
  xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
  xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
  xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
   &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
     &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
     &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
     &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
     &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
     &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
     &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
       &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
           393234.393701,5207990.085063&lt;br /&gt;
           495769.579719,5305374.105135&lt;br /&gt;
         &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
       &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
     &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
     &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
         &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
           &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
             393865.671855,5300138.258409&lt;br /&gt;
             393869.171975,5300138.258374 &lt;br /&gt;
             394516.694141,5300137.439369 &lt;br /&gt;
             395522.728579,5300136.241770 &lt;br /&gt;
             [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE WMS&lt;br /&gt;
   CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
     &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
     &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
     &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  METADATA&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? SERVICE=WFS&lt;br /&gt;
  &amp;amp; REQUEST=getCapabilities&lt;br /&gt;
  &amp;amp; map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
  dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
  &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
  &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34419</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34419"/>
		<updated>2009-01-23T07:28:07Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* getFeatureInfo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
      ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
      &amp;amp; VERSION=1.1.0&lt;br /&gt;
      &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
      &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
      &amp;amp; SRS=EPSG:4326&lt;br /&gt;
      &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
      &amp;amp; WIDTH=500&lt;br /&gt;
      &amp;amp; HEIGHT=500&lt;br /&gt;
      &amp;amp; X=250&lt;br /&gt;
      &amp;amp; Y=250&lt;br /&gt;
      &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
 Layer 'countyboundary'&lt;br /&gt;
   Feature 26: &lt;br /&gt;
     AREA = '7577272785.15393'&lt;br /&gt;
     PERIMETER = '436617.07762'&lt;br /&gt;
     CTY_NAME = 'Itasca'&lt;br /&gt;
     COUN = '31'&lt;br /&gt;
     CTY_ABBR = 'ITAS'&lt;br /&gt;
     ISLAND = 'N'&lt;br /&gt;
     CTY_FIPS = '61'&lt;br /&gt;
     RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     ...&lt;br /&gt;
	 &amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DUMP TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;msGMLOutput &lt;br /&gt;
  xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
  xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
  xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
   &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
     &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
     &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
     &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
     &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
     &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
     &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
     &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
       &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
           393234.393701,5207990.085063&lt;br /&gt;
           495769.579719,5305374.105135&lt;br /&gt;
         &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
       &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
     &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
     &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
         &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
           &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
             393865.671855,5300138.258409&lt;br /&gt;
             393869.171975,5300138.258374 &lt;br /&gt;
             394516.694141,5300137.439369 &lt;br /&gt;
             395522.728579,5300136.241770 &lt;br /&gt;
             [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CONNECTIONTYPE WMS&lt;br /&gt;
   CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
     &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
     &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
     &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  METADATA&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? SERVICE=WFS&lt;br /&gt;
  &amp;amp; REQUEST=getCapabilities&lt;br /&gt;
  &amp;amp; map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
  dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
  &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
  &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34418</id>
		<title>HBUMNMapServer ger Capter 3</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_3&amp;diff=34418"/>
		<updated>2009-01-23T07:24:50Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* UMN als WMS Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Astrid Emde]] (SLD, WMC, Filter Encoding, OWS Clients)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:jtmapmedia | Jörg Thomsen]] (OGC-Konformität, Warum macht man das?, Wie macht man das? )&lt;br /&gt;
&lt;br /&gt;
[[HBUMNMapServer_ger | '''Inhaltsverzeichnis''']]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OGC-Konformität =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:52, 10 January 2009 (UTC)&lt;br /&gt;
(1)\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Das [http://www.opengeospatial.org/ Open Geospatial Consortium]~\cite{http:website:ogc}, kurz OGC, ist ein internationaler Zusammenschluß von '368 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 Geodaten zu erarbeiten.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
   &lt;br /&gt;
* OGC Web Map Service Specification (WMS), für den Transfer von Rasterkarten und eventuelle Anfragen auf diese Daten,&lt;br /&gt;
* OGC Web Feature Service Specification (WFS), was das gleiche für Vektordaten und eventuelle Anfragen auf diese Daten ist.&lt;br /&gt;
* OGC Web Coverage Service Specification (WCS), regelt den Zugriff auf hochaufgelöste Rasterdaten wie Luft- und Satellitenbilder und deren Bereitstellung.&lt;br /&gt;
* OGC Sensor Observation Service (SOS), der den Austausch von Sensordaten, wie z.B. Wasserpegel oder Temperaturmessungen spezifiziert.&lt;br /&gt;
* Map Context Specification, ermöglicht das Speichern und Laden von WMS-Zuständen wie Zoomstufe, sichtbare Layer usw..&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus werfen wir auch noch einen raschen Blick auf&lt;br /&gt;
&lt;br /&gt;
* OGC Filter Encoding (FE), damit können Geodaten, beispielsweise für Klassifizierungen, gefilter werden.&lt;br /&gt;
* OGC Styled Layer Descriptors (SLD), eine Spezifikation, die es ermöglicht die Kartengestaltung eines entfernten WMS zu beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Die Website des OGC ist unter~[[http:website:ogc]] zu erreichen. Zu allen genannten Diensten, und zu vielen weiteren, finden Sie dort auch die Spezifikationen als PDF-Dateien. Sehen Sie sie sich ruhig einmal an. Nachdem Sie die ersten 20 bis 30 Seiten überblättert haben, finden Sie vor dem Anhang die interessanten Informationen auf meist wenigen Seiten zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Warum macht man das?=&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 13:56, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine berechtigte Frage ist natürlich, warum man diese Funktionalität überhaupt haben wollen könnte. Die Antworten sind vielfältig. Hier einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
\subsubsection* {'''Kein Zugang zu den Originaldaten'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Lastenverteilung'''}&lt;br /&gt;
&lt;br /&gt;
Ä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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Herstellerunabhängigkeit'''}&lt;br /&gt;
&lt;br /&gt;
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. Heutzutage gibt es eine große Zahl OGC-konformer Programme, die sich nahezu beliebig miteinander verknüpfen lassen, so kann eine als WMS konfigurierter UMN MapServer seine Karte problemlos an verschiedene Klienten sowohl im Browser (z.N. Mapbender, OpanLayers) als auch auf dem Desktop (z.B. Quantum GIS, gvSIG) ausliefern und einen wichtigen Teil zur Geodateninfrastruktur beitragen.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsection*{'''Existenz von Evaluationskriterien'''}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Solch ein Evaluationsvorgang kann zeitlich und finanziell sehr aufwändig sein. Weithin anerkannte Standards helfen dabei, Entscheidungen anhand fertig vorliegender Kriterienkataloge zu treffen.&lt;br /&gt;
&lt;br /&gt;
= Wie macht man das? =&lt;br /&gt;
--[[User:Jtmapmedia|Jtmapmedia]] 18:00, 10 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Eine UMN MapServer-Anwendung OGC-konform zu gestalten ist keine Hexerei, Sie benötigen nicht einmal eine Erweiterung und müssen auch nichts neu kompilieren - es sind lediglich einige Erweiterungen im Mapfile notwendig. Bevor wir uns aber wieder dem Mapfile zuwenden, ein paar Sätze das grundsätzliche Verständnis der Funktionsweise von OGC-Diensten fördern.&lt;br /&gt;
&lt;br /&gt;
Der Aufruf eines WMS-Servers erfolgt ganz ähnlich dem Aufruf des UMN MapServers, nämlich über einen URL mit den gewünschten Parametern, Sie werden im Folgenden bemerken, dass auch andere Aufrufe, wie WFS oder WCS, dem gleichen Muster folgen. 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.&lt;br /&gt;
&lt;br /&gt;
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 muss, 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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{'''Hinweis'''}&amp;lt;br&amp;gt;&lt;br /&gt;
In der Version 4.x war MapServer sehr tolerant, einige würden sagen nicht voll OGC-konform, weil er nicht alle Aufrufparameter verlangte, die die Spezifikation vorschreibt. Wenn Sie beim Aufruf eines WMS ab UMN Version einen laut Spezifikation erforderlichen Parameter weglassen, wird das nun mit einer Fehlermeldung quittiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun aber ein Beispiel für einen WMS-konformen URL des MapServers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt; Beispielaufruf dem aktuellen OSM/Hamburg-Beispiel anpassen.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? SERVICE=WMS&lt;br /&gt;
     &amp;amp; VERSION=1.1.1&lt;br /&gt;
     &amp;amp; REQUEST=GetMap&lt;br /&gt;
     &amp;amp; FORMAT=image/png&lt;br /&gt;
     &amp;amp; LAYERS=gruenflaechen,fluesse,bebauung&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; STYLES,,,&lt;br /&gt;
  #hier enden die Pflichtparameter, Auftritt zweier optionaler Parameter:&lt;br /&gt;
     &amp;amp; TRANSPARENT=TRUE&lt;br /&gt;
     &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie werden sich jetzt fragen, wo denn der Hinweis auf das Mapfile geblieben ist, den Sie bisher immer mit angeben mussten. Ein Parameter ''map''  ist in der WMS-Spezifikation allerdings nirgends erwähnt. Wie man sich dieses Parameters entledigen kann, erfahren Sie weiter unten auf Seite~\pageref{text:wms:mapfilename}.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter ''SERVICE'' gibt an, welche Spezifikation genutzt werden soll. Wir möchten eine Karte im PNG-Format abrufen, die im Browser angezeigt werden soll, also benutzen wir den Web Map Service.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Es gibt aber auch Dienste, die diese Schreibweise ewarten.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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. Mehr zu diesem Thema, das oft zu schwer identifizierbaren Fehlern führt und einige Nerven kosten kann, finden Sie im Anhang &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME:&amp;lt;/span&amp;gt; Verweis auf den noch zu erstellenden Anhang.&lt;br /&gt;
&lt;br /&gt;
''BBOX'': Ähnlich wie die anzuzeigenden Kartenebenen werden auch die gewünschten Extents durch mehrere Werte angefordert, die in einer Liste durch Kommata voneinander getrennt sind. Achten Sie immer darauf, dass die Werte der BBOX mit dem SRS korrespondieren.&lt;br /&gt;
&lt;br /&gt;
''WIDTH''  und ''HEIGHT''  geben die Größe in Pixeln vor, die die fertige Karte haben soll. Beachten Sie, dass diese Werte mit der BBOX korrelieren müssen; eine quadratische BBOX in Verbindung mit ungleicher Höhe und Breite führt zu einer Verzerrung des Kartenbildes.&lt;br /&gt;
&lt;br /&gt;
Der Parameter ''STYLES'' gibt für jeden Layer eine Darstellungsoption an (sofern der Provider des Service dieses mit den sog. ''Named Styles'' vorbereitet hat). Sie müssen keine Styles angeben, der Parameter im GetMap-Aufruf ist jedoch Pflicht.&lt;br /&gt;
&lt;br /&gt;
Mit ''TRANSPARENT'' wird die Hintergrundfarbe der Karte transparent geschaltet. Das will man offensichtlich dann haben, wenn man unter dieser Kartenebene noch andere Layer anzeigen möchte.&lt;br /&gt;
&lt;br /&gt;
Schließlich und endlich wird dem WMS im obigen Beispiel mitgeteilt in welcher Form Fehlermeldungen ausgegeben werden, in unserem Fall soll die Fehlermeldung in resultierende Rasterbild gerendert werden. Wenn Sie eine XML-formatierte Fehlermeldung bevorzugen verwenden Sie ''application/vnd.ogc.se_xml''.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Aufrufes ist also eine 500 mal 500 Pixel große, auf EPSG-Code &amp;lt;span style=&amp;quot;background-color:yellow;&amp;quot;&amp;gt;FIXME: &amp;lt;/span&amp;gt;4326&amp;lt;/span&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Map Service (WMS)=&lt;br /&gt;
==UMN als WMS Server==&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Servermodi==(2)&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= : Diese Anfrage muss ein XML-Dokument zurückliefern, das die Fähigkeiten des Mapservers beschreibt.  &lt;br /&gt;
*=getMap= : Auf diese Anfrage wird eine Karte als Rasterbild zurückgeliefert.  &lt;br /&gt;
&lt;br /&gt;
Entsprechend der Anforderung sind diese beiden Anfragen auch im MapServer implementiert.&lt;br /&gt;
&lt;br /&gt;
Die beiden Fähigkeiten, die implementiert sein ''können'' , sind:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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.  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Das einzige Feature, das im MapServer zurzeit nicht implementiert ist, ist demnach =describeLayer= . Es gibt noch einige andere Modi; mehr dazu in Abschnitt~7&lt;br /&gt;
&lt;br /&gt;
==WMS-Metadaten im Mapfile==\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Zuallererst benötigt ihr Mapfile einen Namen. Im Header muß also der Parameter =NAME=  definiert sein.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Ein WMS-Server&amp;quot;&lt;br /&gt;
     &amp;quot;wms_onlineresource&amp;quot; \&lt;br /&gt;
        &amp;quot;http://www.example.com/cgi-bin/mapserv?map=mapfile.map&amp;amp;&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31464 EPSG:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Beachten Sie dabei, das =\&amp;amp;=  anzugeben, bzw. ein Fragezeichen, wenn Sie nach dem eigentlichen CGI-Programm keinen Parameter zu stehen haben.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=lcc&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=49&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=-95&amp;quot;&lt;br /&gt;
   &amp;quot;lat_1=49&amp;quot;&lt;br /&gt;
   &amp;quot;lat_2=77&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie nun EPSG-Codes in =wms_srs=  nach außen anbieten, werden die Daten automatisch umprojiziert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notwendige Metadaten in den Layern}&lt;br /&gt;
&lt;br /&gt;
Des weiteren müssen nun in jedem Layer zusätzliche Angaben nach folgendem Muster gemacht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;einlayer&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   METADATA&lt;br /&gt;
     &amp;quot;wms_title&amp;quot; &amp;quot;Titel fuer den Layer&amp;quot;&lt;br /&gt;
     &amp;quot;wms_srs&amp;quot;  &amp;quot;EPSG:31494&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in der Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Eine elaborierte Zusammenfassung dessen, was der Server soll und ist.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_address=  Die Adresse.    &lt;br /&gt;
*=wms_city=  Adressbestandteil: Stadt    &lt;br /&gt;
*=wms_country=  Adressbestandteil: Land    &lt;br /&gt;
*=wms_postcode=  Adressbestandteil: Postleitzahl    &lt;br /&gt;
*=wms_stateorprovince=  Adressbestandteil: Staat oder Provinz    &lt;br /&gt;
*=wms_contactelectronicmailaddress=  Emailadresse einer Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactoraganization=  Organisation der Kontaktperson    &lt;br /&gt;
*=wms_contactperson=  Name der Kontaktperson für diesen Server    &lt;br /&gt;
*=wms_contactposition=  Position der Kontaktperson innerhalb ihrer Organisation    &lt;br /&gt;
*=wms_contactvoicetelephone=  Telefonnummer der Kontaktperson    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=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.    &lt;br /&gt;
*=wms_onlineresource=  Der URL, mit dem der Server aufgerufen wird. Beinhaltet beim UMN MapServer meistens:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  http://www.example.com/cgi-bin/mapserv?  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    und gegebenenfalls daran angehängt noch das Mapfile. Wenn ein Mapfile über =map==  angehangen wird, darf nicht das abschließende =\&amp;amp;=  vergessen werden! Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
*=wms_resx=  Horizontale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_resy=  Vertikale Auflösung der Karte in Pixeln.    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann. Dieser Parameter mit mindestens einer Projektion ist zwingend notwendig.    &lt;br /&gt;
*=wms_title=  Titel der Karte. Dieser Parameter ist zwingend notwendig.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Metadaten in den einzelnen Layern}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=wms_abstract=  Elaborierte Zusammenfassung dessen, was dieser Layer soll und ist.    &lt;br /&gt;
*=wms_extent=  Die Bounding Box des Layers.    &lt;br /&gt;
*=wms_keywordlist=  Eine Liste von Schlüsselworten, die auf diesen Server zutreffen.    % &lt;br /&gt;
*=wms_opaque=  FIXME: was ist das?    &lt;br /&gt;
*=wms_srs=  Projektion(en), in der die Karte angeboten werden kann.    &lt;br /&gt;
*=wms_title=  Titel des Layers. Dieser Parameter ist zwingend erforderlich.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile als Parameter}(4)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Im Moment gibt es zwei verschiedene Wege, den Ort des Mapfiles vor Außenstehenden zu verbergen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*''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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  #!/bin/sh  MS_MAPFILE=/usr/local/there/is/my.map  export MS_MAPFILE  /usr/local/httpd/cgi-bin/mapserv  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    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.    &lt;br /&gt;
*''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):    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  SetEnvIf Request_URI &amp;quot;/cgi-bin/mapserv&amp;quot; \    MS_MAPFILE=/usr/local/there/is/my.map  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Eintrag funktioniert nur im Apache und kann für andere Webserver vollkommen anders aussehen. Konsultieren Sie Ihre Dokumentation.    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getCapabilities}(5)&lt;br /&gt;
&lt;br /&gt;
Nachdem man zufrieden mit seinem Setup ist, möchte man es natürlich ausprobieren. Dazu ruft man als erstes das ''Capabilities'' -Dokument ab:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://server/cgi-bin/mapserv?VERSION=1.1.0&amp;amp;REQUEST=getCapabilities \&lt;br /&gt;
      &amp;amp;map=mapfile.map &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei müssen Sie bei =getCapabilities=  nicht auf Groß- oder Kleinbuchstaben achten. Ebensowenig bei allen anderen Parametern, die vor einem Gleichheitszeichen stehen.&lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich nun den Inhalt der Datei genau an. Wo immer Sie auf Zeilen treffen, die&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: ... --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
beinhalten, gilt es, etwas zu bereinigen. Beispielsweise erfahren Sie aus einer Warnung wie dieser:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;!-- WARNING: Mandatory metadata 'wms_title' was missing&lt;br /&gt;
      in this context --&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dass Sie einen Meta-Tag für den Titel der entsprechenden Sektion vergessen haben.&lt;br /&gt;
&lt;br /&gt;
Sobald Sie keine Warnungen dieser Art mehr in Ihrem Capabilities-Dokument finden, ist ihr MapServer WMS-konform und voll einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==\index{Exceptions}\index{WMS!Exceptions}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;?xml version='1.0' encoding=&amp;quot;ISO-8859-1&amp;quot; standalone=&amp;quot;no&amp;quot; ?&amp;gt;  &amp;lt;!DOCTYPE ServiceExceptionReport SYSTEM   &amp;quot;http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd&amp;quot;&amp;gt;    &amp;lt;ServiceExceptionReport version=&amp;quot;1.1.0&amp;quot;&amp;gt;      &amp;lt;ServiceException&amp;gt;        msWMSDispatch(): WMS server error. Incomplete WMS        request: REQUEST parameter missing      &amp;lt;/ServiceException&amp;gt;    &amp;lt;/ServiceExceptionReport&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.6}{wms-exception-inimage}{Exception vom Typ application/vnd.ogc.se_inimage.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann ein Mapserver Exceptions in den folgenden MIME-Typen zur Verfügung stellen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=application/vnd.ogc.se_inimage=  Die Exception wird als Text in das auszuliefernde Bild eingefügt.  &lt;br /&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.  &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; EXCEPTIONS=application/vnd.ogc.se_inimage &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Hinweis===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==getFeatureInfo==&lt;br /&gt;
&lt;br /&gt;
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= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn man das tut, und sich die ''capabilities''  anschaut, wird man für den Layer auf ein Attribut der folgenden Art treffen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;Layer queryable=&amp;quot;1&amp;quot; opaque=&amp;quot;0&amp;quot; cascaded=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =1=  für =queryable=  zeigt im Gegensatz zum Wert =0=  an, dass Queries auf diesen Layer zulässig sind.&lt;br /&gt;
&lt;br /&gt;
Um einen Aufruf vom Typ =getFeatureInfo=  zu verstehen, betrachten wir einmal einen vollständigen URL für diesen Vorgang:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
     ? map=/usr/local/mapserv/mapfile.map&lt;br /&gt;
     &amp;amp; VERSION=1.1.0&lt;br /&gt;
     &amp;amp; REQUEST=getFeatureInfo&lt;br /&gt;
     &amp;amp; QUERY_LAYERS=gruenflaechen&lt;br /&gt;
     &amp;amp; SRS=EPSG:4326&lt;br /&gt;
     &amp;amp; BBOX=5.0,45.0,15.0,55.0&lt;br /&gt;
     &amp;amp; WIDTH=500&lt;br /&gt;
     &amp;amp; HEIGHT=500&lt;br /&gt;
     &amp;amp; X=250&lt;br /&gt;
     &amp;amp; Y=250&lt;br /&gt;
     &amp;amp; INFO_TYPE=text/plain&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Bestandteile sind dem Leser bereits bekannt: Version des Standards, Angabe der Projektion durch =SRS= . Dazu kommt, wenig überraschend, die Angabe des =REQUEST= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Am interessantesten ist natürlich der =INFO_TYPE= , der angibt, auf welche Weise die Queryergebnisse formatiert sein sollen. MapServer unterstützt die folgenden Formate:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=text/plain= , das Standardformat, falls Sie nichts anderes angegeben haben;  &lt;br /&gt;
*=text/html= , was ein wenig Vorbereitung erfordert, im wesentlichen aber wie Queries auf einem 'normalen' MapServer-CGI behandelt wird; und  &lt;br /&gt;
*=application/vnd.ogc.gml= , GML, eine XML-Repräsentation für Geodaten.  &lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Formate im Detail:&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/plain}&lt;br /&gt;
&lt;br /&gt;
Dieser Ausgabetyp für getFeatureInfo ist die Voreinstellung für MapServer, falls Sie keinen anderen Ausgabentyp spezifizieren.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
GetFeatureInfo results:&lt;br /&gt;
&lt;br /&gt;
Layer 'countyboundary'&lt;br /&gt;
  Feature 26: &lt;br /&gt;
    AREA = '7577272785.15393'&lt;br /&gt;
    PERIMETER = '436617.07762'&lt;br /&gt;
    CTY_NAME = 'Itasca'&lt;br /&gt;
    COUN = '31'&lt;br /&gt;
    CTY_ABBR = 'ITAS'&lt;br /&gt;
    ISLAND = 'N'&lt;br /&gt;
    CTY_FIPS = '61'&lt;br /&gt;
    RECNO = '27'&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{text/html}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  METADATA&lt;br /&gt;
    ...&lt;br /&gt;
	&amp;quot;wms_feature_info_mime_type&amp;quot; &amp;quot;text/plain&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{application/vnd.ogc.gml}&lt;br /&gt;
&lt;br /&gt;
Damit ein Layer in diesem Format Anfragen beantworten kann, muß außerdem der Parameter =DUMP=  in diesem Layer gesetzt sein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
 ...&lt;br /&gt;
 DUMP TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;msGMLOutput &lt;br /&gt;
 xmlns:gml=&amp;quot;http://www.opengis.net/gml&amp;quot;&lt;br /&gt;
 xmlns:xlink=&amp;quot;http://www.w3.org/1999/xlink&amp;quot;&lt;br /&gt;
 xmlns:xsi=&amp;quot;http://www.w3.org/2000/10/XMLSchema-instance&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;countyboundary_layer&amp;gt;&lt;br /&gt;
  &amp;lt;countyboundary_feature&amp;gt;&lt;br /&gt;
    &amp;lt;AREA&amp;gt;7577272785.15393&amp;lt;/AREA&amp;gt;&lt;br /&gt;
    &amp;lt;PERIMETER&amp;gt;436617.07762&amp;lt;/PERIMETER&amp;gt;&lt;br /&gt;
    &amp;lt;CTY_NAME&amp;gt;Itasca&amp;lt;/CTY_NAME&amp;gt;&lt;br /&gt;
    &amp;lt;COUN&amp;gt;31&amp;lt;/COUN&amp;gt;&lt;br /&gt;
    &amp;lt;CTY_ABBR&amp;gt;ITAS&amp;lt;/CTY_ABBR&amp;gt;&lt;br /&gt;
    &amp;lt;ISLAND&amp;gt;N&amp;lt;/ISLAND&amp;gt;&lt;br /&gt;
    &amp;lt;CTY_FIPS&amp;gt;61&amp;lt;/CTY_FIPS&amp;gt;&lt;br /&gt;
    &amp;lt;RECNO&amp;gt;27&amp;lt;/RECNO&amp;gt;&lt;br /&gt;
    &amp;lt;gml:boundedBy&amp;gt;&lt;br /&gt;
      &amp;lt;gml:Box srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
          393234.393701,5207990.085063&lt;br /&gt;
          495769.579719,5305374.105135&lt;br /&gt;
        &amp;lt;/gml:coordinates&amp;gt;&lt;br /&gt;
      &amp;lt;/gml:Box&amp;gt;&lt;br /&gt;
    &amp;lt;/gml:boundedBy&amp;gt;&lt;br /&gt;
    &amp;lt;gml:Polygon srsName=&amp;quot;EPSG:26915&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;gml:outerBoundaryIs&amp;gt;&lt;br /&gt;
        &amp;lt;gml:LinearRing&amp;gt;&lt;br /&gt;
          &amp;lt;gml:coordinates&amp;gt;&lt;br /&gt;
            393865.671855,5300138.258409&lt;br /&gt;
            393869.171975,5300138.258374 &lt;br /&gt;
            394516.694141,5300137.439369 &lt;br /&gt;
            395522.728579,5300136.241770 &lt;br /&gt;
            [...]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter, mit allen Punkten des Features.&lt;br /&gt;
&lt;br /&gt;
==WMS Clients==\index{OGC!Client}(6)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Installation und Konfiguration}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{getMap}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Mapfile}&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Für WMS-konforme Anfragen an andere Server sind lediglich die Layerdefinitionen anzupassen. Dabei kommt ein =CONNECTIONTYPE=  mit dem Namen =WMS=  zum Einsatz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CONNECTIONTYPE WMS&lt;br /&gt;
  CONNECTION &amp;quot;http://www.example.com/cgi-bin/mapserv?&amp;quot;&lt;br /&gt;
  METADATA&lt;br /&gt;
    &amp;quot;wms_title&amp;quot;          &amp;quot;Gewaesser&amp;quot;&lt;br /&gt;
    &amp;quot;wms_server_version&amp;quot; &amp;quot;1.1.0&amp;quot;&lt;br /&gt;
    &amp;quot;wms_srs&amp;quot;            &amp;quot;EPSG:4326 EPSG:31464&amp;quot;&lt;br /&gt;
    &amp;quot;wms_name&amp;quot;           &amp;quot;seen,kanaele,fluesse,baeche&amp;quot;&lt;br /&gt;
    &amp;quot;wms_format&amp;quot;         &amp;quot;image/png&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:31464&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie Sie sehen, ist der URL selber sehr kurz gehalten. Er entspricht der ''onlineresource''  aus dem Capabilities-Dokument eines WMS-konformen Servers.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Der =wms_title=  ist der Titel für diesen Layer, der mit der Anfrage allerdings nichts zu schaffen hat.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
''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.&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt offensichtlich bei =application/vnd.ogc.se_blank= .&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Hinweise==(7)&lt;br /&gt;
&lt;br /&gt;
FIXME: das auch noch bei WFS erwähnen&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Weitere Modi für WMS}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=describeLayer=   &lt;br /&gt;
*=getLegendGraphic=   &lt;br /&gt;
*=getStyles=   &lt;br /&gt;
*=putStyles=   &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
=Web Feature Server (WFS)=(8)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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]].&lt;br /&gt;
&lt;br /&gt;
Von den in der Spezifikation definierten Anfragetypen sind im MapServer die folgenden implementiert:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=getCapabilities= , um ein Capabilities-Dokument abrufen zu können, wie man es bereits von WMS kennt.  &lt;br /&gt;
*=describeFeature=  liefert eine Beschreibung eines Features zurück.  &lt;br /&gt;
*=getFeature=  holt eine GML-Repräsentation eines Features.  &lt;br /&gt;
&lt;br /&gt;
==WFS Server==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*Zuerst muß MapServer natürlich mit WFS-Unterstützung kompiliert worden sein. Detaillierte Vorgaben dafür finden Sie in Anhang~\ref{anhang:compile}.  &lt;br /&gt;
*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.  &lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
In der =WEB= -Sektion des Mapfiles müssen dann die folgenden Angaben gemacht werden.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=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:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  WEB    ..    METADATA    ...      &amp;quot;wfs_onlineresource&amp;quot; \  	  &amp;quot;http://www.example.com/cgi-bin/mapserv?SERVICE=WFS&amp;amp;map=...&amp;quot;    END  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Diese Angabe ist auch dann nötig, wenn der MapServer nicht darauf eingerichtet oder konfiguriert ist, als WMS-Server zu fungieren.    &lt;br /&gt;
*=wfs_title=  Titel für die Karte; siehe WMS-Konformität. Zwingend notwendig.  &lt;br /&gt;
*=wfs_abstract=  Eine elaborierte Zusammenfassung über Sinn und Zweck dieses Servers. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_keywordlist=  Eine Liste mit Schlüsselworten, die einen Bezug zu diesem WFS-Server haben. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_accessconstraints=  Beschränkungen, die den Zugriff auf diesen Server betreffen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_fees=  Gebühren, die beim Zugriff auf diesen Server anfallen. Siehe WMS-Konformität.  &lt;br /&gt;
*=wfs_encoding=  Die Kodierung für die XML-Dateien, die durch den WFS-Server ausgeliefert werden. Voreingestellt ist hier ISO-8859-1.  &lt;br /&gt;
*=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}.  &lt;br /&gt;
*=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= .  &lt;br /&gt;
*=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.  &lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass diese Parameter im Gegensatz zu den WMS-Parametern alle den Präfix =wfs_=  tragen. Einzige Ausnahme ist =ows_schema_location= .&lt;br /&gt;
&lt;br /&gt;
==Projektionen in WFS-Servern==&lt;br /&gt;
&lt;br /&gt;
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ß.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Gibt es keine solche 'Überprojektion', muß jeder Layer einen eigenen Wert setzen.&lt;br /&gt;
&lt;br /&gt;
==Schemas==(9)&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  METADATA&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;quot;ows_schema_location&amp;quot; &amp;quot;/pfad/zu/den/schemas&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.}.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Aufruf \&amp;amp; Capabilities==&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? SERVICE=WFS&lt;br /&gt;
  &amp;amp; REQUEST=getCapabilities&lt;br /&gt;
  &amp;amp; map=...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==WFS Client==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Ein WFS-Client-Layer ist sieht anders aus als ein 'normaler' Layer, hat aber Ähnlichkeit mit einem WMS-konformen Layer. Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Map Context=&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Das Dokument, das diesen Standard definiert ist in der Version 1.0 von der OGC-Website herunterladbar~[[pdf:spec:mapcontext10]].&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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}.&lt;br /&gt;
&lt;br /&gt;
==Das Context-Dokument==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
==Den Kontext verwenden==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie ein Mapfile nach den obigen Vorgaben erstellt haben, können Sie testen, ob Sie alles richtig gemacht haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
  dl (&amp;quot;php_mapscript40.so&amp;quot;);&lt;br /&gt;
  &amp;lt;math&amp;gt;map = ms_newMapObj (&amp;quot;mapfile.map&amp;quot;);&lt;br /&gt;
  &amp;lt;/math&amp;gt;map -&amp;gt; saveMapContext (&amp;quot;mapfile_context.xml&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
FIXME: fertig!1!&lt;br /&gt;
&lt;br /&gt;
= Styled Layer Descriptor (SLD)=&lt;br /&gt;
* http://www.mapserver.org/ogc/sld.html &lt;br /&gt;
&lt;br /&gt;
=Filter Encoding =&lt;br /&gt;
[[User:Astrid Emde]]&lt;br /&gt;
    * http://www.mapserver.org/ogc/filter_encoding.html&lt;br /&gt;
&lt;br /&gt;
= WCS =&lt;br /&gt;
    * http://de.wikipedia.org/wiki/Web_Coverage_Service&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_server.html&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wcs_format.html&lt;br /&gt;
&lt;br /&gt;
= WMS Time=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/wms_time.html &lt;br /&gt;
&lt;br /&gt;
= SOS=&lt;br /&gt;
&lt;br /&gt;
    * Informationen siehe http://www.mapserver.org/ogc/sos_server.html &lt;br /&gt;
&lt;br /&gt;
== OWS Clients ==&lt;br /&gt;
=== Desktop GIS ===&lt;br /&gt;
=== WebGIS ===&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34417</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34417"/>
		<updated>2009-01-23T07:07:55Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* PostgreSQL und PostGIS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
   FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   CLASS&lt;br /&gt;
     TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 gemeinden_header.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 QUERYMAP&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
   SIZE 200 200&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   STYLE HILITE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
    queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
    [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
   FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   FILTER &amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;png&amp;quot;&lt;br /&gt;
   DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
   IMAGEMODE RGB&lt;br /&gt;
   EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
   DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
   IMAGEMODE RGB&lt;br /&gt;
   EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
   FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
   DRIVER PDF&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 OUTPUTFORMAT&lt;br /&gt;
   NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
   MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
   DRIVER swf&lt;br /&gt;
   IMAGEMODE PC256&lt;br /&gt;
   FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
   # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 FEATURE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     10 10&lt;br /&gt;
     10 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
   STATUS DEFAULT&lt;br /&gt;
   TRANSFORM FALSE&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   FEATURE&lt;br /&gt;
     POINTS&lt;br /&gt;
       10 10&lt;br /&gt;
     END&lt;br /&gt;
     TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
       SIZE 11&lt;br /&gt;
       ANTIALIAS TRUE&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END									 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
    &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
   LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34416</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34416"/>
		<updated>2009-01-23T07:04:42Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* featurequery und featurenquery */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
   FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   CLASS&lt;br /&gt;
     TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 gemeinden_header.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 QUERYMAP&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
   SIZE 200 200&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   STYLE HILITE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
    queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
    [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
   FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   FILTER &amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34415</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34415"/>
		<updated>2009-01-23T07:03:51Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* itemquery und itemnquery */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
   FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   CLASS&lt;br /&gt;
     TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 gemeinden_header.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 QUERYMAP&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
   SIZE 200 200&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   STYLE HILITE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
    queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
    [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   ...&lt;br /&gt;
   DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
   FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   FILTER &amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34414</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34414"/>
		<updated>2009-01-23T07:02:56Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* indexquery */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
   FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   CLASS&lt;br /&gt;
     TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 gemeinden_header.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 QUERYMAP&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
   SIZE 200 200&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   STYLE HILITE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
    queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
    [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34413</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34413"/>
		<updated>2009-01-23T07:00:33Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Notation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
   FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
   CLASS&lt;br /&gt;
     TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 gemeinden_header.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden.html&lt;br /&gt;
 gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 QUERYMAP&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
   SIZE 200 200&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   STYLE HILITE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
    queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
    [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34412</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34412"/>
		<updated>2009-01-23T06:55:56Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Aufbau */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 METADATA&lt;br /&gt;
   autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
   adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 Der Autor [autor] kann unter&lt;br /&gt;
 der Adresse [adresse] erreicht werden&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34411</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34411"/>
		<updated>2009-01-23T06:53:19Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Aufbau */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
   &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
   &amp;lt;body&amp;gt;&lt;br /&gt;
     &amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34410</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34410"/>
		<updated>2009-01-23T06:51:59Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Legenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     [leg_layer_name]&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34409</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34409"/>
		<updated>2009-01-23T06:50:41Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Legenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
     &amp;lt;div&amp;gt;[leg_layer_name]&amp;lt;/div&amp;gt;&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34408</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34408"/>
		<updated>2009-01-23T06:46:21Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Legenden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
   ... hier passiert etwas ...&lt;br /&gt;
 }&lt;br /&gt;
 else {&lt;br /&gt;
   ... hier passiert etwas anderes ...&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html]&lt;br /&gt;
   [if name=layer_type oper=eq value=2]&lt;br /&gt;
     &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
   [/if]&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 [leg_layer_html opt_flag=3]&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&lt;br /&gt;
     &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
  	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 [/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34407</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34407"/>
		<updated>2009-01-23T06:43:15Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Annotationen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   ...&lt;br /&gt;
   CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     ...&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE NORMAL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       POSITION CR&lt;br /&gt;
       PARTIALS TRUE&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE SMALL&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TYPE ANNOTATION&lt;br /&gt;
   DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
   LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE TRUETYPE&lt;br /&gt;
       FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
       SIZE 12&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
       OUTLINECOLOR 255 255 255&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
     3 3&lt;br /&gt;
     3 1&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
   TYPE TRUETYPE&lt;br /&gt;
   FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
   ANTIALIAS TRUE&lt;br /&gt;
   CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
   TYPE PIXMAP&lt;br /&gt;
   IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
   TRANSPARENT 0&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   SYMBOL 0&lt;br /&gt;
   SIZE 4&lt;br /&gt;
   COLOR 0 0 0&lt;br /&gt;
   OVERLAYSYMBOL 0&lt;br /&gt;
   OVERLAYSIZE 2&lt;br /&gt;
   OVERLAYCOLOR 255 0 0&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
   TYPE ELLIPSE&lt;br /&gt;
   POINTS&lt;br /&gt;
     1 1&lt;br /&gt;
   END&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   STYLE 2 2 1 1 &lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SYMBOL&lt;br /&gt;
   NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
   TYPE VECTOR&lt;br /&gt;
   FILLED TRUE&lt;br /&gt;
   POINTS&lt;br /&gt;
     0 .375&lt;br /&gt;
     .35 .375&lt;br /&gt;
     .5 0&lt;br /&gt;
     .65 .375&lt;br /&gt;
     1 .375&lt;br /&gt;
     .75 .625&lt;br /&gt;
     .875 1&lt;br /&gt;
     .5 .75&lt;br /&gt;
     .125 1&lt;br /&gt;
     .25 .625&lt;br /&gt;
   END&lt;br /&gt;
 END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34406</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34406"/>
		<updated>2009-01-23T06:37:37Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Vektordaten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
   TYPE POLYGON&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 255 240 128&lt;br /&gt;
     OUTLINECOLOR 128 120 64&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   GRID&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 0&lt;br /&gt;
     LABEL&lt;br /&gt;
       TYPE BITMAP&lt;br /&gt;
       SIZE TINY&lt;br /&gt;
       COLOR 0 0 0&lt;br /&gt;
     END&lt;br /&gt;
   END&lt;br /&gt;
   PROJECTION&lt;br /&gt;
     &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
   &amp;quot;zone=15&amp;quot;&lt;br /&gt;
   &amp;quot;north&amp;quot;&lt;br /&gt;
   &amp;quot;no_defs&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 PROJECTION&lt;br /&gt;
   &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
   &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
   &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
   &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 arial   arial.ttf&lt;br /&gt;
 times   times.ttf&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34405</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34405"/>
		<updated>2009-01-23T06:36:00Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Rasterdaten mit GDAL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34404</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34404"/>
		<updated>2009-01-23T06:34:39Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Rasterdaten klassifizieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
     COLOR 255 0 0&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34403</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34403"/>
		<updated>2009-01-23T06:32:25Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Weitere Layer-Optionen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
 END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
 CLASS&lt;br /&gt;
   ...&lt;br /&gt;
   TEXT (GK:[gk-zone])&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASS&lt;br /&gt;
     COLOR 0 0 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
   DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
   TYPE LINE&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
     COLOR 255 31 31&lt;br /&gt;
   END&lt;br /&gt;
   CLASS&lt;br /&gt;
     EXPRESSION /./&lt;br /&gt;
     COLOR 31 31 255&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
   COLOR 255 0 0&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
   COLOR 0 0 255&lt;br /&gt;
 END&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION /./&lt;br /&gt;
   OUTLINECOLOR 128 128 128&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
   COLOR 32 64 218&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 CLASS&lt;br /&gt;
   EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
   STYLE&lt;br /&gt;
     SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
     COLOR 32 64 218&lt;br /&gt;
   END&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER &lt;br /&gt;
   NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
   DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 thfischer@grobi # ./mapserv -v&lt;br /&gt;
 MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
 OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
 SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
 INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
   TYPE RASTER&lt;br /&gt;
   STATUS ON&lt;br /&gt;
   TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
   TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34402</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34402"/>
		<updated>2009-01-23T06:30:35Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Gruppierungen von Layern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
  &lt;br /&gt;
 LAYER&lt;br /&gt;
   NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
   GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34401</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34401"/>
		<updated>2009-01-23T06:29:10Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Die Web-Sektion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34400</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34400"/>
		<updated>2009-01-23T06:28:41Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Der Header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
 EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
 SIZE      450 450&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 MAP&lt;br /&gt;
   NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
   SIZE 400 400&lt;br /&gt;
   ...&lt;br /&gt;
 END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34399</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34399"/>
		<updated>2009-01-23T06:27:35Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Bedeutung des Mapfiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 WEB&lt;br /&gt;
   ...&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
 STATUS ON&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
 DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
 EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
 SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 COLOR   0   0   0  # schwarz&lt;br /&gt;
 COLOR 255 255 255  # weiß&lt;br /&gt;
 COLOR 255   0   0  # rot&lt;br /&gt;
 COLOR   0 255   0  # grün&lt;br /&gt;
 COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34398</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34398"/>
		<updated>2009-01-23T05:40:02Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Bedeutung des Mapfiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34389</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34389"/>
		<updated>2009-01-22T19:35:00Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Die klassische MapServer-Legende */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
 ==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
 LEGEND&lt;br /&gt;
   ...&lt;br /&gt;
   TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
 END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34388</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34388"/>
		<updated>2009-01-22T19:30:33Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Annotationen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen_annotation&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    ...&lt;br /&gt;
    CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      ...&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE NORMAL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        POSITION CR&lt;br /&gt;
        PARTIALS TRUE&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE SMALL&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TYPE ANNOTATION&lt;br /&gt;
    DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
    LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE TRUETYPE&lt;br /&gt;
        FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
        SIZE 12&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
        OUTLINECOLOR 255 255 255&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
      3 3&lt;br /&gt;
      3 1&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
    TYPE TRUETYPE&lt;br /&gt;
    FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
    ANTIALIAS TRUE&lt;br /&gt;
    CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
    TYPE PIXMAP&lt;br /&gt;
    IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
    TRANSPARENT 0&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    SYMBOL 0&lt;br /&gt;
    SIZE 4&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    OVERLAYSYMBOL 0&lt;br /&gt;
    OVERLAYSIZE 2&lt;br /&gt;
    OVERLAYCOLOR 255 0 0&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
    TYPE ELLIPSE&lt;br /&gt;
    POINTS&lt;br /&gt;
      1 1&lt;br /&gt;
    END&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    STYLE 2 2 1 1 &lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SYMBOL&lt;br /&gt;
    NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
    TYPE VECTOR&lt;br /&gt;
    FILLED TRUE&lt;br /&gt;
    POINTS&lt;br /&gt;
      0 .375&lt;br /&gt;
      .35 .375&lt;br /&gt;
      .5 0&lt;br /&gt;
      .65 .375&lt;br /&gt;
      1 .375&lt;br /&gt;
      .75 .625&lt;br /&gt;
      .875 1&lt;br /&gt;
      .5 .75&lt;br /&gt;
      .125 1&lt;br /&gt;
      .25 .625&lt;br /&gt;
    END&lt;br /&gt;
  END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34387</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34387"/>
		<updated>2009-01-22T19:25:40Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Vektordaten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
    TYPE POLYGON&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 255 240 128&lt;br /&gt;
      OUTLINECOLOR 128 120 64&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    GRID&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      LABEL&lt;br /&gt;
        TYPE BITMAP&lt;br /&gt;
        SIZE TINY&lt;br /&gt;
        COLOR 0 0 0&lt;br /&gt;
      END&lt;br /&gt;
    END&lt;br /&gt;
    PROJECTION&lt;br /&gt;
      &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
    &amp;quot;zone=15&amp;quot;&lt;br /&gt;
    &amp;quot;north&amp;quot;&lt;br /&gt;
    &amp;quot;no_defs&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
    &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
    &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
    &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  arial   arial.ttf&lt;br /&gt;
  times   times.ttf&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34385</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34385"/>
		<updated>2009-01-22T19:23:00Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Rasterdaten mit GDAL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  # gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34384</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34384"/>
		<updated>2009-01-22T19:21:44Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Rasterdaten klassifizieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
      COLOR 255 0 0&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34383</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34383"/>
		<updated>2009-01-22T19:18:42Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Weitere Layer-Optionen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASS&lt;br /&gt;
      COLOR 0 0 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
    DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
    TYPE LINE&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
      COLOR 255 31 31&lt;br /&gt;
    END&lt;br /&gt;
    CLASS&lt;br /&gt;
      EXPRESSION /./&lt;br /&gt;
      COLOR 31 31 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    OUTLINECOLOR 128 128 128&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
    STYLE&lt;br /&gt;
      SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
      COLOR 32 64 218&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER &lt;br /&gt;
    NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
    DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  thfischer@grobi # ./mapserv -v&lt;br /&gt;
  MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
  OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
  SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
  INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
    TYPE RASTER&lt;br /&gt;
    STATUS ON&lt;br /&gt;
    TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
    TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34382</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34382"/>
		<updated>2009-01-22T19:15:11Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Gruppierungen von Layern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
  &lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
    COLOR 255 31 31&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 31 31 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
  COLOR 0 0 255&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /./&lt;br /&gt;
  OUTLINECOLOR 128 128 128&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
  COLOR 32 64 218&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  STYLE&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER &lt;br /&gt;
  NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
  DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
thfischer@grobi # ./mapserv -v&lt;br /&gt;
MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
  TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34381</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34381"/>
		<updated>2009-01-22T19:14:30Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Gruppierungen von Layern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
  LAYER&lt;br /&gt;
    NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
    GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  ...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
    COLOR 255 31 31&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 31 31 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
  COLOR 0 0 255&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /./&lt;br /&gt;
  OUTLINECOLOR 128 128 128&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
  COLOR 32 64 218&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  STYLE&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER &lt;br /&gt;
  NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
  DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
thfischer@grobi # ./mapserv -v&lt;br /&gt;
MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
  TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34380</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34380"/>
		<updated>2009-01-22T19:12:23Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Der Header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
  SIZE      450 450&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  MAP&lt;br /&gt;
    NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
    SIZE 400 400&lt;br /&gt;
    ...&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
    COLOR 255 31 31&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 31 31 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
  COLOR 0 0 255&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /./&lt;br /&gt;
  OUTLINECOLOR 128 128 128&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
  COLOR 32 64 218&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  STYLE&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER &lt;br /&gt;
  NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
  DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
thfischer@grobi # ./mapserv -v&lt;br /&gt;
MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
  TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34379</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34379"/>
		<updated>2009-01-22T19:11:13Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Die weiteren Parameter */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
  EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
SIZE      450 450&lt;br /&gt;
SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
MAP&lt;br /&gt;
  NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  SIZE 400 400&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
    COLOR 255 31 31&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 31 31 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
  COLOR 0 0 255&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /./&lt;br /&gt;
  OUTLINECOLOR 128 128 128&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
  COLOR 32 64 218&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  STYLE&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER &lt;br /&gt;
  NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
  DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
thfischer@grobi # ./mapserv -v&lt;br /&gt;
MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
  TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34378</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34378"/>
		<updated>2009-01-22T19:10:16Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Grundlegender Aufbau des Mapfiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
 =Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
  STATUS ON&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
  DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
   EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
  SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  COLOR   0   0   0  # schwarz&lt;br /&gt;
  COLOR 255 255 255  # weiß&lt;br /&gt;
  COLOR 255   0   0  # rot&lt;br /&gt;
  COLOR   0 255   0  # grün&lt;br /&gt;
  COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
SIZE      450 450&lt;br /&gt;
SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
MAP&lt;br /&gt;
  NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  SIZE 400 400&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
    COLOR 255 31 31&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 31 31 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
  COLOR 0 0 255&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /./&lt;br /&gt;
  OUTLINECOLOR 128 128 128&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
  COLOR 32 64 218&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  STYLE&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER &lt;br /&gt;
  NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
  DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
thfischer@grobi # ./mapserv -v&lt;br /&gt;
MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
  TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
	<entry>
		<id>https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34377</id>
		<title>HBUMNMapServer ger Capter 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.osgeo.org/w/index.php?title=HBUMNMapServer_ger_Capter_2&amp;diff=34377"/>
		<updated>2009-01-22T19:06:02Z</updated>

		<summary type="html">&lt;p&gt;Wiki-Mikee63: /* Grundlegender Aufbau des Mapfiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Lars]] (logging, includes, fastcgi)&amp;lt;br&amp;gt;&lt;br /&gt;
[[User:Simon Appelt]] (Web-Sektion, Layer, Weitere Layer-Optionen)&lt;br /&gt;
= Mapfile =&lt;br /&gt;
\index{Mapfile}&lt;br /&gt;
&lt;br /&gt;
Das Mapfile wird Ihnen größte Freude bereiten. Sie werden die meisten Ihrer Fehler damit machen, und die meiste Zeit, die Sie mit dem MapServer überhaupt verbringen, wird das Editieren Ihrer Mapfiles zum Inhalt haben.&lt;br /&gt;
&lt;br /&gt;
=Bedeutung des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Das Mapfile ist die zentrale Layout- und Konfigurationsdatei einer MapServer-Anwendung,sozusagen das &amp;quot;Herz&amp;quot;. Sie beschreibt Inhalt und Darstellung der fertigen Karte und enthält zusätzliche Informationen, um Maßstäbe, Legenden und Referenzkarten passend zur fertigen Karte zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Auch die Metadaten, die zur OGC-konformen Funktionsweise benötigt werden, sind im Mapfile angegeben.&lt;br /&gt;
&lt;br /&gt;
Bevor wir jedoch in alle Details des Mapfiles einsteigen, werfen wir einen Blick auf die generelle Funktionsweise des MapServers.&lt;br /&gt;
&lt;br /&gt;
==MapServer als CGI==\index{CGI}(2)&lt;br /&gt;
&lt;br /&gt;
Dies ist der &amp;quot;Standard&amp;quot;-Weg, den MapServer zu benutzen: indem er als Programm in einem Webserver wie beispielsweise dem Apache residiert. Über den URL bekommt das Programm Parameter zugewiesen und ändert seine Ausgabe anhand dieser Parameter.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Ein typischer URL sieht etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
       ? map=/usr/local/www/mapfile.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist für den Druck umgebrochen, es handelt sich um eine einzige Zeile, und die Leestellen im URL sind ebenfalls nur für die Lesbarkeit hinzugefügt. Backslashes an den Enden zeigen an, dass die Zeile noch nicht beendet ist. Diese Unix-typische Notation wird im folgenden im ganzen Buch Verwendung finden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass die Domain =example.com=  für anschauliche Zwecke in der Literatur~[[rfc2606]] reserviert ist und Ihnen ''kein Ergebnis''  bei einem Aufruf anzeigen wird. Ersetzen Sie diesen Domainnamen durch den tatsächlichen Namen Ihres Hosts.&lt;br /&gt;
&lt;br /&gt;
Der MapServer, das eigentliche Programm, das die Arbeit macht, liegt offensichtlich in einem =cgi-bin=  genannten Verzeichnis des Webservers. Ruft man ihn einfach ohne Parameter auf, also etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann sollte man als Antwort folgendes in seinem Browser sehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
No query information to decode. QUERY_STRING is set, but empty.&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{motzing}{Der MapServer motzt herum; genau das, was man am Anfang sehen möchte.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Also wie in Abbildung~\ref{motzing}. Wie reagiert man darauf? Indem man sich freut, denn alles ist in Ordnung; hurra, er kann schon rummotzen! Dies ist die Meldung, die man sehen möchte. MapServer beschwert sich lediglich, dass er keine Parameter zur Verarbeitung genannt bekommen hat. Nach einer neuen Installation ist diese Meldung nach dem ersten Testaufruf das gewünschte Ergebnis.&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter wird mit einem Fragezeichen =?=  eingeleitet, alle weiteren werden mit einem Kaufmanns-Und =\&amp;amp;=  voneinander getrennt.&lt;br /&gt;
&lt;br /&gt;
Zwingend notwendig ist die Angabe eines Mapfiles über den Parameter =map== \footnote{Man kann diese Preisgabe des Ortes, an dem das Mapfile liegt, auch nach außen verbergen. Mehr dazu später.}, damit dem MapServer bekannt ist, welches Layout für die Karte zur Anwendung kommen soll.&lt;br /&gt;
&lt;br /&gt;
Liegt Ihr Mapfile unter Unix etwa unter =/usr/local/maps/mymap.map= , so wäre also folgender Aufruf korrekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv?map=/usr/local/maps/mymap.map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pfade unter Windows werden ebenfalls so angegeben, wie Sie es gewohnt sind, also beispielweise mit =C:=  am Anfang.&lt;br /&gt;
&lt;br /&gt;
==Die Modi==&lt;br /&gt;
&lt;br /&gt;
MapServer kennt nun verschiedene Betriebs''modi'' , die über den Parameter =mode==  notiert werden. Es gibt die folgenden Modi:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=browse= : Läßt Sie die Karte browsen. Das bedeutet im wesentlichen, dass MapServer die Templates berücksichtigt, die im Mapfile angegeben sind, und somit HTML-Dateien mit Navigationselementen ausliefert. Wenn kein Modus angegeben ist, geht MapServer immer von =browse=  aus. Was es mit Templates genau auf sich hat, erfahren Sie in Abschnitt~20 ab Seite~\pageref{text:mapfile:templates}.  &lt;br /&gt;
*=map= : Dieser Modus läßt den MapServer Template-Angaben ignorieren und nur die Karte ausliefern. Zum Testen Ihres Mapfiles ist dies wahrscheinlich genau der Modus, den Sie haben möchten.  &lt;br /&gt;
*=query= : Dieser Modus und seine Funktion, das Abfragen von Daten, die der Karte zugrunde liegen, werden ab Seite~\pageref{text:mapfile:queries} beschrieben.   &lt;br /&gt;
*=nquery= : Wo =query=  immer nur ein Ergebnis zurückliefern kann, kann =nquery=  mehrere Ergebnisse liefern, sowohl im gleichen Layer als auch aus verschiedenen Layern (und auch beides zusammen, natürlich). Die Template-Angaben für diesen Modus können recht umfangreich sein.  &lt;br /&gt;
&lt;br /&gt;
Wenn Sie also Ihr Mapfile =mymap.map=  im Modus =map=  aufrufen wollten -- wodurch lediglich eine Karte, aber kein HTML-Interface produziert würde --, würden Sie folgendes notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Die weiteren Parameter==&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, die das Aussehen einer Karte beeinflussen können, werden über solche Parameter übergeben. Das schließt das Mapfile und den Modus mit ein, und darüberhinaus \ldots\ nun, eben alles andere, inklusive der Kartenebenen, die Sie sehen möchten, die Eckpunkte des gewünschten Kartenausschnitts, und noch diverse andere Dinge mehr. Da kann ein URL schnell einmal wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
     http://www.example.com/cgi-bin/mapserv \&lt;br /&gt;
     ? map=/usr/local/maps/mymap.map \&lt;br /&gt;
     &amp;amp; mode=map \&lt;br /&gt;
     &amp;amp; layer=postleitzahlen&amp;amp;layer=fluesse&amp;amp;layer=strassen \&lt;br /&gt;
     &amp;amp; imgext=18.0+9.0+30.0+15.0&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und sie kann noch viel viel länger werden. Und Ihr erster Gedanke, wenn Sie das sehen, ist natürlich vollkommen korrekt: Das will kein Mensch jedesmal eintippen müssen.&lt;br /&gt;
&lt;br /&gt;
Daher werden diese Parameter für gewöhnlich über Eingaben in einem HTML-Formular generiert. Dazu gehört dann beispielsweise auch die Karte, die Sie im Browserfenster anklicken. Diese Formulare werden aus den Templates generiert, die weiter oben schon einmal erwähnt worden sind.&lt;br /&gt;
&lt;br /&gt;
Für das erste setzen wir uns ausschließlich mit der Gestaltung der Karte auseinander, wofür Sie nur den Modus =map=  ohne zusätzliche Parameter benötigten. Wenn ab Seite~\pageref{text:mapfile:templates} die Templates dazukommen, wird Ihr Wissen um eine Navigation in der Karte erweitert. Ab Seite~\pageref{text:mapfile:cgiparams} finden Sie schließlich eine Aufzählung aller möglichen CGI-Parameter.&lt;br /&gt;
&lt;br /&gt;
Neben der CGI-Fassung gibt es zwei weitere Wege, die Funktionalitäten des MapServers zu nutzen. Beide unterscheiden sich zum Teil radikal von der Weise, die in diesem Kapitel behandelt wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Der OGC-konforme MapServer}\index{OGC}&lt;br /&gt;
&lt;br /&gt;
Der OGC-konforme MapServer arbeitet ebenfalls als CGI-Programm und muß vor allen Dingen mit Metadaten versorgt werden, die dann bei der Kommunikation mit anderen Servern und mit Client-Appli\-ka\-tio\-nen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Leider weicht sowohl die Notation des aufrufenden URL als auch die Notation der Metadaten im Mapfile ein wenig von der des MapServers im 'Normalbetrieb' ab, was nicht zur Lesbarkeit der ganzen Datei beiträgt. Die Unterschiede in der Notation werden im entsprechenden Kapitel ab Seite~\pageref{text:ogc} natürlich erläutert.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{MapScript}\index{MapScript}&lt;br /&gt;
&lt;br /&gt;
MapScript muß nicht gezwungenermaßen mit einem Mapfile arbeiten, z.B. wenn man damit nur Shapefiles bearbeiten möchte. Sobald man beginnt, mit Karten arbeiten zu wollen, wird man jedoch auch mit MapScript ein Mapfile laden, das dann verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Alle Sektionen im Mapfile werden dann als Objekte in einer Programmiersprache behandelt. Grundsätzlich ist nicht einmal ein Webserver vonnöten, auch lokale Applikationen lassen sich mit MapScript realisieren. &lt;br /&gt;
&lt;br /&gt;
Am häufigsten sieht man MapScript jedoch in seiner Variante für PHP im Einsatz, die dann natürlich wieder in Webservern läuft. Als Beispiel konzentrieren wir uns in diesem Handbuch auf eben diese Version von MapScript.&lt;br /&gt;
&lt;br /&gt;
=Grundlegender Aufbau des Mapfiles=&lt;br /&gt;
&lt;br /&gt;
Werfen wir zuerst einen ganz allgemeinen Blick darauf, wie Inhalte im Mapfile notiert werden, bevor dann näher beschrieben wird, welche Einträge es denn gibt.&lt;br /&gt;
&lt;br /&gt;
Das Mapfile besteht aus einzelnen Blöcken, die mit einem Schlüsselwort beginnen und mit einem =END=  abgeschlossen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
  WEB&lt;br /&gt;
    ...&lt;br /&gt;
  END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Beginn und das Ende eines =WEB= -Blocks. Innerhalb eines solchen Blocks folgen Deklarationen von Schlüsselworten und dazugehörigen Werten, oder wieder neue Blöcke. Beispiele für Blöcke in Blöcken sind Classes innerhalb von Layern.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen für diese Notation sind der Header des Mapfiles und das Mapfile selber, das zwar mit einem END abgeschlossen werden muss, aber kein einleitendes Schlüsselwort kennt.&lt;br /&gt;
&lt;br /&gt;
Wann immer im folgenden drei Punkte in Beispielen zu sehen sind, sollen diese Punkte nicht tatsächlich eingegeben werden; es handelt sich vielmehr um Platzhalter, die zeigen, dass etwas weggelassen worden ist.&lt;br /&gt;
&lt;br /&gt;
Es können drei verschiedene Dinge als Werte notiert werden: Schlüsselworte, Zahlen oder Zeichenketten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SCHLÜSSELWORT SCHLÜSSEL&lt;br /&gt;
STATUS ON&lt;br /&gt;
&lt;br /&gt;
SCHLÜSSELWORT &amp;quot;ZEICHENKETTE&amp;quot;&lt;br /&gt;
DATA &amp;quot;myshapefile&amp;quot;&lt;br /&gt;
&lt;br /&gt;
SCHLÜSSELWORT ZAHL [ZAHL ...]&lt;br /&gt;
EXTENT 0 0 4000 4000&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Schlüsselworten und Zeichenketten ist es bei Zahlen in den meisten Fällen nötig, mehr als nur eine zu schreiben. So benötigt man für den Extent einer Karte stets vier Zahlen, die die beiden Koordinaten jeweils eines Eckpunktes bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sollten generell nicht mit Zahlen beginnen: =zweiterlayer=  ist als Layername in Ordnung, =2terlayer=  nicht.&lt;br /&gt;
&lt;br /&gt;
Ausnahmen dazu bilden Angaben zu Projektionen von Karten und Layern und die Metadaten in diversen Sektionen. Deren Notation wird in den entsprechenden Abschnitten näher beschrieben.&lt;br /&gt;
&lt;br /&gt;
Zwei Arten von Angaben verdienen besondere Beachtung: Pfade in das Dateisystem und Farben.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Notation von Pfaden}&lt;br /&gt;
&lt;br /&gt;
Pfade können absolute oder relative Angaben sein. Absolute Angaben sehen etwa folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SHAPEPATH &amp;quot;c:\mapserver\daten&amp;quot;&lt;br /&gt;
SHAPEPATH &amp;quot;/usr/local/GIS/daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Absolute Pfade heißen so, weil sie den vollständigen Pfad von der Wurzel des Dateisystems bis hin zur Datei angeben.&lt;br /&gt;
&lt;br /&gt;
Relative Pfade bewegen sich immer in Relation zu etwas, in unserem Fall zum Mapfile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SHAPEPATH &amp;quot;daten/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall gibt es also im Verzeichnis des Mapfiles ein Unterverzeichnis mit dem Namen =daten= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Farbwerte}&lt;br /&gt;
&lt;br /&gt;
Farben werden als RGB-Werte angegeben, also bestehend aus ihren jeweiligen Anteilen von Rot, Grün und Blau, in Werten von 0 bis 255\footnote{Dadurch lassen sich theoretisch &amp;lt;math&amp;gt;2^{24}&amp;lt;/math&amp;gt; Farben, also die bekannten 16 Millionen darstellen}. Einige Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
COLOR   0   0   0  # schwarz&lt;br /&gt;
COLOR 255 255 255  # weiß&lt;br /&gt;
COLOR 255   0   0  # rot&lt;br /&gt;
COLOR   0 255   0  # grün&lt;br /&gt;
COLOR   0   0 255  # blau&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und so weiter. Farben, bei denen alle drei Zahlen gleich sind, ergeben Grautöne. Im Web finden sich einige Farb- und Umrechnungstabellen.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte: Ohne weitere Angaben zum Ausgabeformat -- siehe Seite~\pageref{text:mapfile:ausgabeformate} -- produziert MapServer nur Bilder mit einer Palette von 256 Farben. Mehr über Farben in MapServer erfahren Sie in eben diesem Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=Der Header=&lt;br /&gt;
\index{Header}\index{Mapfile!Header}(3)&lt;br /&gt;
&lt;br /&gt;
Der Header im Mapfile enthält globale Angaben, die sich auf alle Sektionen im&lt;br /&gt;
Mapfile beziehen oder das Aussehen des fertigen Bildes bestimmen, das produziert&lt;br /&gt;
werden soll. Der Header ist die einzige Sektion, die nicht durch ein END&lt;br /&gt;
abgeschlossen wird. Er besitzt auch kein einleitendes Schlüsselwort.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für einen kompletten Header\footnote{Um keinen Fehler im Modus =map=  zu produzieren, reichen eigentlich schon SIZE und EXTENT, zusammen mit einem END für ein vollständiges Mapfile.}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
NAME      &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
EXTENT    0.0 0.0 1.0 1.0&lt;br /&gt;
SIZE      450 450&lt;br /&gt;
SHAPEPATH &amp;quot;daten/brandenburg/&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Angaben im Header Ihres Mapfiles machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Ein Name als Beschreibung der Karte. Dieser Name sollte einzigartig sein und im weiteren nicht als Name für Layer verwendet werden. Der Name der Karte wird für WMS-konforme Aufrufe verwendet -- siehe auch das entsprechende Kapitel --, als auch als Prefix für die Namen temporär erzeugter Dateien des MapServer.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;= : Der Status der Karte, ob an oder aus. Da man ein Mapfile normalerweise schreibt, um eine Karte anzuzeigen, drängt sich =ON=  geradezu auf.\\ Ausschalten will man das nur dann, wenn man nur die anderen Elemente benutzen will, die man im Mapfile definiert, also zum Beispiel Maßstäbe und Legenden.    &lt;br /&gt;
*=EXTENT &amp;lt;minx miny maxx maxy&amp;gt;= : Eine Bounding Box um die Daten herum. Wird im URL für den MapServer keine Bounding Box explizit angegeben, ist diese Angabe im Mapfile eine Standardeinstellung, die automatisch verwendet wird. Dieser Wert muß zwingendermaßen vorhanden sein.\\ Sorgen Sie dafür, dass hier ein sinnvoller Wert steht. MapServer ist nicht in der Lage, aus den vorliegenden Daten einen 'Default'-Extent zu ermitteln. Auf das Problem angesprochen, meinten die Entwickler, so ein Feature auch nicht implementieren zu wollen, zumal einige Datenformate gar keinen Extent speichern und das Errechnen aus den Daten selbst viel zu aufwendig wäre.     &lt;br /&gt;
*=SIZE &amp;lt;width height&amp;gt;= : Die Größe des zu produzierenden Bildes, anzugeben in Breite und Höhe in Pixeln. Auch dies ist eine Voreinstellung, die Verwendung findet, wenn es keine andere explizite Angabe gibt. Die Größe des zu produzierenden Bildes ist auf 2048 Pixel im Quadrat beschränkt.    &lt;br /&gt;
*=SHAPEPATH &amp;lt;path&amp;gt;= : Der Ort im Dateisystem, an dem die Daten liegen. Kann ein relativer Pfad zum Mapfile sein, oder ein absoluter, der irgendwo anders in das lokale Dateisystem weist.    &lt;br /&gt;
*=SYMBOLSET &amp;lt;filename&amp;gt;= : Die Datei, in der Symbole definiert werden. Was es mit Symbolen auf sich hat, und wie Symbole im Mapfile selber anstatt in einer separaten Datei notiert werden können, erfahren Sie in Abschnitt~17.    &lt;br /&gt;
*=FONTSET &amp;lt;filename&amp;gt;= : Die Datei, die Aliase für TrueType-Schriften enthält. Zum Aufbau dieser Datei und der Verwendung von Schriften im MapServer siehe den Abschnitt ab Seite~\pageref{text:mapfile:fonts}.    &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red green blue&amp;gt;= : Hintergrundfarbe des fertigen Kartenbildes, in RGB-Werten.    &lt;br /&gt;
*=IMAGEFORMAT &amp;lt;name&amp;gt;= : Name des Ausgabeformats, das produziert werden soll. Muß ein interner Name für ein Bildformat sein, oder der Name eines Ausgabeformates, der mit einer =OUTPUTFORMAT= -Sektion definiert worden ist. Mehr zu Ausgabeformaten finden Sie ab Seite~\pageref{text:mapfile:ausgabeformate}.    &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Das Wort MAP}&lt;br /&gt;
&lt;br /&gt;
Sie können ein Mapfile auch mit dem Schlüsselwort =MAP=  einleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
MAP&lt;br /&gt;
  NAME &amp;quot;brandenburg&amp;quot;&lt;br /&gt;
  SIZE 400 400&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist nicht notwendig. Sie können so allerdings dem abschließenden =END=  am Ende des Mapfiles sozusagen einen Startparameter zur Seite stellen. Es sieht hübscher aus, hat aber keine Funktion.&lt;br /&gt;
&lt;br /&gt;
=Die Web-Sektion= &lt;br /&gt;
\index{Web}\index{Mapfile!Web}&lt;br /&gt;
&lt;br /&gt;
Der Web-Block im Mapfile definiert das Verhalten des MapServer-Interface nach außen und beinhaltet URLs für verschiedene Gelegenheiten, einige interne Informationen, die nicht nach außen weitergegeben werden, sowie eventuell Metadaten für verschiedene Anwendungsfälle, für gewöhnlich zum Beispiel für OGC-konformes Verhalten.&lt;br /&gt;
&lt;br /&gt;
Der Web-Block wird mit den Schlüsselwort =WEB=  eingeleitet und durch ein =END=  abgeschlossen.&lt;br /&gt;
	&lt;br /&gt;
'Web' ist als Name eigentlich irreführend, da die Daten in diesem Abschnitt nicht notwendigerweise nur von Web-Diensten genutzt werden. Aber der MapServer wurde als Web-Applikation entwickelt, und daher ist es unwahrscheinlich, dass sich an dieser Benennung etwas ändern wird.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Elemente können in der Web-Sektion verwendet werden:&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=ERROR &amp;lt;url&amp;gt;= \index{ERROR}: Definiert einen URL, an den der Benutzer weitergeleitet wird, wenn ein Fehler in der MapServer-Applikation auftritt. Kann eine absolute URL sein, die mit =http://=  eingeleitet wird, oder ein Pfad relativ zur Lage des Mapfiles. Wird =ERROR=  nicht definiert, wird einfach nur die Fehlernachricht als Text ausgegeben.\\ Beachten Sie dabei, dass das für das Debuggen während der Entwicklung Ihrer Anwendung nicht begehrenswert ist, da keine der MapServer-Fehlermeldungen mehr ausgegeben werden. Das will man für gewöhnlich nur für das fertige System haben, sobald man seine Benutzer nicht mehr mit den Fehlermeldungen des MapServers konfrontieren möchte, sondern mit einer hübschen Fehlerseite.    &lt;br /&gt;
*=EMPTY &amp;lt;url&amp;gt;= \index{EMPTY}: URL, an den der Benutzer weitergeleitet wird, wenn ein Query keine Resultate erbracht hat. Wenn =EMPTY=  nicht definiert ist, wird dafür der Wert von =ERROR=  benutzt.    &lt;br /&gt;
*=FOOTER &amp;lt;filename&amp;gt;= \index{FOOTER}: Der Fußteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=HEADER &amp;lt;filename&amp;gt;= \index{HEADER}: Der Kopfteil einer fertigen Ausgabe. Kommt nur bei Queries zur Anwendung, die mehrere Ergebnisse zurückliefern sollen.    &lt;br /&gt;
*=TEMPLATE &amp;lt;url|filename&amp;gt;= \index{TEMPLATE}: Das Template, das das eigentliche Interface zum Benutzer darstellt. Darstellung der Karte und die Navigation darin werden durch das Template übernommen. Der Aufbau eines Templates wird detailliert in Abschnitt~20 behandelt.    &lt;br /&gt;
*=IMAGEPATH= \index{IMAGEPATH}: Der Pfad zu dem Verzeichnis, in dem die vom MapServer generierten Bilder abgelegt werden sollen. Dieser Pfad muß auf dem System existieren und muß vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Diese Angabe muß mit dem Verzeichnistrenner der jeweiligen Plattform enden, also =/=  auf Unix-Systemen und so weiter.    &lt;br /&gt;
*=IMAGEURL= \index{IMAGEURL}: Der URL zum genannten =IMAGEPATH= . =IMAGEURL=  wird vom Webbrowser zurückgegeben und muß daher im Webserver so konfiguriert sein, dass =IMAGEURL=  auf =IMAGEPATH=  abgebildet wird.    Auf Unix-Systemen wird meistens der URL =/tmp=  auf das lokale Verzeichnis =/tmp/=  (oder auch =/var/tmp/= ) abgebildet. Damit gibt man jedoch auch sein temporäres Verzeichnis dem öffentlichen Zugriff preis. Sinnvoller ist es, ein eigenes Verzeichnis für diese Dateien anzulegen. Mehr Überlegungen zu diesem Thema finden Sie in Anhang~\ref{anhang:sicherheit}.    &lt;br /&gt;
*=LOG &amp;lt;filename&amp;gt;= \index{LOG}: Die Logdatei für den MapServer. Diese Datei muß auf dem System existieren und muss vom Webserver (bzw. von dem Benutzer, mit dessen Rechten der Webserver läuft) beschreibbar sein. Mehr zu Log-Dateien erfahren Sie weiter unten in Abschnitt~31.   &lt;br /&gt;
*=METADATA&amp;lt;filename&amp;gt;= \index{LOG}: Die Sektion Metadata ermöglicht es, weiterführende Informationen über den WMS-Dienst bereitzustellen, um nach aussen eine gewisse Transparents zu schaffen. So gibt es zum Beispiel den erforderlichen Parameter &amp;quot;wms_title&amp;quot;, über dem das Kind einen Namen bekommt. Nähre Information zu den einzelenen Parametern, finden Sie im Kapitell 3, Sektion 3.2.3 WMS-Metadaten im Mapfile. &lt;br /&gt;
*=MINSCALEDENOM= \index{MINSCALE}: Der minimale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem kleineren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MINSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MAXSCALEDENOM= \index{MAXSCALE}: Der maximale =SCALE= , in dem Karten zu sehen sind. Wird eine Karte mit einem größeren =SCALE=  vom Client angefordert, liefert MapServer eine Karte in dem =SCALE=  zurück, der =MAXSCALE=  entspricht. Mehr zur Verwendung von =SCALE= -ähnlichen Parametern im Mapfile finden Sie in Sektion~19.    &lt;br /&gt;
*=MINTEMPLATE= \index{MINTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  unter =MINSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
*=MAXTEMPLATE= \index{MAXTEMPLATE}: Template, das anstelle von =TEMPLATE=  benutzt werden soll, wenn der Client eine Karte angefordert hat, deren =SCALE=  über =MAXSCALEDENOM=  liegt. Mit einem solchen Template lassen sich Applikationen ineinander verschachteln, indem ab bestimmten Zoomtiefen einfach andere Templates benutzt werden.    &lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEQUALITY= , mit dem sich Kompressionsraten für produzierte JPEG-Bilder setzen ließ, wird nicht mehr unterstützt. Verwenden Sie stattdessen einen entsprechenden Parameter in einer =OUTPUTFORMAT= -Sektion (siehe weiter hinten). Das gleiche gilt für =INTERLACED= .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Layer= &lt;br /&gt;
\index{Layer}\index{Mapfile!Layer} &lt;br /&gt;
&lt;br /&gt;
MapServer organisiert seine Daten in Schichten, die übereinander liegen -- eben den Layern. Diese Schichten werden dann zu einem fertigen Bild zusammengefügt. Einzelne Sets von Raster- oder Polygondaten müssen jeweils in einen eigenen Layer eingebunden werden. Über die Layer werden auch Queries definiert, die dazu verwendet werden, Anfragen an zusätzlich gespeicherte Daten zu stellen. Auf diese Weise können beispielsweise Flächen angeklickt und detaillierte Informationen zu diesen angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
Bei nicht-OGC-konformen MapServern spielt die Reihenfolge der Layer im Mapfile eine wichtige Rolle. &lt;br /&gt;
Dies können sie sich wie eine Art Stapelverarbeitung vorstellen. Der Layer, der oben auf dem Stapel liegt, wird als erstes abgearbeitet und gezeichnet, somit liegt dieser in der Kartendarstellung ganz unten. Rasterbilder bieten sich meist als unterster Layer an. Auf den ersten Layer wird dann der zweite Layer im Mapfile gezeichnet, und so weiter. &lt;br /&gt;
&lt;br /&gt;
Wir betrachten im folgenden den Aufbau eines Vektorlayers mit Zugriff auf ein Shapfile. Rasterdaten werden in Abschnitt~7 besprochen.&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;= : Ein Name als Beschreibung des Layers. Mehrere Layer können identische Namen tragen und werden dann als ein einziger Layer behandelt. Diese Vorgehensweise wird manchmal für Beschriftungen (Annotationen, siehe weiter hinten) gewählt, um in einem Zug den Layer samt Beschriftung ein- oder ausblenden zu können. Ansonsten sollte der Name so gewählt werden, dass er eindeutig ist. Um mögliche Fehlerquellen bei der Wahl des Layernames von vornherein zu vermeiden, &lt;br /&gt;
ist es empfehlenswert den Layernamen so zu bestimmen, dass weder Sonderzeichen, noch Zahlen und Umlaute enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=DATA &amp;lt;filename&amp;gt;= : Der Dateiname des Shapefiles. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles. Die Zeichenkette hier wird also einfach angehangen. Der Name sollte ohne den Anhang ''.shp''  angegeben werden.    Bitte beachten Sie, dass die zum Shapefile gehörige ''.dbf'' -Datei immer vorhanden sein muss, auch wenn man nicht auf ihren Inhalt zugreift. Das gleiche gilt natürlich auch für die Indexdatei mit der Endung ''.shx'' , nur wird diese ja beim Zugriff auf das Shape tatsächlich verwendet.    Des weiteren können Sie hier auch einfach den absoluten Pfadnamen einer Datei angeben.    &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|DEFAULT&amp;gt;= : Der Status des Layers. Es gilt drei verschiedene Stadien zu unterscheiden.    =DEFAULT=  stellt den betreffenden Layer auf jeden Fall dar, unabhängig davon, ob der Benutzer ihn über den URL anfordert. Auf diese Weise läßt sich die Darstellung beispielsweise eines Hintergrundbildes erzwingen, ohne dass man ihn von außen abschalten kann. =OFF=  stellt den Layer gar nicht da, unabhängig davon, ob er von außen angefordert worden ist. =ON=  hingegen macht den Layer darstellbar, und er wird angezeigt, wenn er über den entsprechenden Parameter des URL angefordert worden ist.    &lt;br /&gt;
*=TYPE &amp;lt;POINT|LINE|POLYGON&amp;gt;= : Für Vektorlayer kommen nur diese drei verschiedenen Typen in Frage.    Punktlayer sind offensichtlich nur für Punktdaten geeignet. Generell lassen sich Linien- und Vektordaten als das jeweils andere darstellen. Das wirkt sich im wesentlich auf die Art und Weise aus, mit der MapServer die Definitionen in den Klassen des Layers interpretiert. Mehr dazu im Abschnitt über Classes.    &lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass in den Layer-Sektionen mit diesen Angaben noch keine Aussagen über das Layout der Daten gemacht werden. Diese Aussagen werden erst in den Klassen innerhalb eines Layers getroffen!&lt;br /&gt;
&lt;br /&gt;
==Gruppierungen von Layern==&lt;br /&gt;
(4)&lt;br /&gt;
\index{Groups}\index{Layer!Groups}&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man mehrere Layer gleichzeitig ansprechen, indem man sie beispielsweise in einem Schwung an- und wieder ausschaltet. Wenn man für jeden dieser Layer einen eigenen Eintrag in der Navigation zuläßt, kann es schnell unübersichtlich werden.&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit ist, zusammengehörigen Layern den gleichen Namen zu geben. Wenn man also drei Layer hat, die beispielsweise Landstraßen, Autobahnen und Bundesstraßen darstellen, kann man sie alle drei =strasse=  nennen und ist fertig.&lt;br /&gt;
&lt;br /&gt;
Das widerspricht jedoch ein wenig der Idee, drei verschiedene Layer zu haben. Man hätte dann ebenso gut alle Daten in einem Shapefile unterbringen  und die Art der Darstellung mit entsprechenden Classes über die Daten in der ''.dbf'' -Datei erledigen können.&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =GROUP=  erlaubt die Gruppierung von Layern unter Beibehaltung ihrer Namen mitsamt der Möglichkeit, sie alle auf einmal ansprechen zu können. Man schaue sich folgendes Fragment an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;autobahnen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;bundesstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;landstrassen&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;strassen&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist es möglich, im URL eines MapServer-Aufrufs weiterhin folgendes zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=landstrassen&amp;amp;layer=autobahnen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gewinnt man aber auch die folgende Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;layer=strassen&amp;amp;...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Layer-Optionen==&lt;br /&gt;
&lt;br /&gt;
Im folgenden eine Liste aller weiteren Schlüsselworte, die in Layern Verwendung finden können. Falls Sie dieses Buch von vorne nach hinten durchlesen\footnote{Sowas soll's geben.}, werden Sie einige der Begriffe wahrscheinlich noch nicht kennen. Sie sollten dann später noch einmal hierher zurückkehren und sich die Bedeutung der Dinge klarmachen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*=REQUIRES &amp;lt;expression&amp;gt;=  Legt bestimmte Voraussetzungen fest, unter denen ein Layer angezeigt wird. Ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    NAME &amp;quot;gruenflaechen&amp;quot;    STATUS ON    REQUIRES &amp;quot;[parks] != 1&amp;quot;    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dieser Layer würde also nur dann angezeigt, wenn ein anderer Layer mit dem Namen =parks=  ''nicht''  zu sehen ist. Logische Operatoren wie =AND=  und =OR=  können hier Verwendung finden.    &lt;br /&gt;
*=MAXSCALE &amp;lt;double&amp;gt;=  Der maximale SCALE, bei dem der Layer noch gezeichnet werden soll. Dieser Wert ist unter Umständen nicht vertrauenswürdig -- siehe auch den Abschnitt~19 über Maßstäbe.  &lt;br /&gt;
*=MINSCALE &amp;lt;double&amp;gt;=  Das gleiche für einen minimalen SCALE.  &lt;br /&gt;
*=LABELANGLEITEM &amp;lt;colname&amp;gt;=  Gibt bei einem Shapefile die Spalte in der ''.dbf'' -Datei an, in der ein Winkel stehen soll, um den ein Label im Layer gedreht werden soll.  &lt;br /&gt;
*=LABELMAXSCALE &amp;lt;integer&amp;gt;=  Der maximale SCALE, in dem Labels in diesem Layer gezeichnet werden sollen. Anmerkungen zu diesem Wert siehe weiter oben.  &lt;br /&gt;
*=LABELMINSCALE &amp;lt;integer&amp;gt;=  Der minimale SCALE, bei dem Labels in diesem Layer noch gezeichnet werden sollen.  &lt;br /&gt;
*=LABELREQUIRES &amp;lt;expression&amp;gt;=  Siehe weiter oben das =REQUIRES= -Schlüsselwort; wirkt sich aber nur auf die Label in einem Layer aus.  &lt;br /&gt;
*=MAXFEATURES &amp;lt;integer&amp;gt;=  Die maximale Anzahl an Features, die in diesem Layer gezeichnet werden sollen.  &lt;br /&gt;
*=OFFSITE &amp;lt;integer&amp;gt;=  Kommt nur bei Rasterbildern zur Anwendung und gibt die Nummer der Farbe in der Farbpalette an, die transparent geschaltet werden soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;true|false&amp;gt;=  Gibt an, ob der Layer vor oder nach allen Labels gezeichnet werden soll. Voreinstellung ist =false= .  &lt;br /&gt;
*=SYMBOLSCALE &amp;lt;double&amp;gt;=  Der SCALE, bei dem Labels (und Symbole) in ihrer vollen Größe gezeichnet werden. Auf diese Weise erreicht man Beschriftungen, die beim Herein- und Herauszoomen mitskalieren.  &lt;br /&gt;
*=TRANSFORM &amp;lt;true|false&amp;gt;=  Definiert, ob ein Layer von dem Koordinatensystem seiner Daten in ein Bildkoordinatensystem transformiert werden soll. Voreinstellung ist =true= . Eine nützliche Funktion, wenn man Bilder an festen Stellen in jeder Karte einbinden möchte, beispielsweise Nordpfeile oder Logos.  &lt;br /&gt;
*=CLASSITEM &amp;lt;colname&amp;gt;= &lt;br /&gt;
*=CLASSGROUP &amp;lt;name&amp;gt;= &lt;br /&gt;
*=CONNECTIONTYP&amp;lt;local|sde|ogr|postgis|oraclespatial|wms&amp;gt;= &lt;br /&gt;
*=CONNECTION &amp;lt;string&amp;gt;= &lt;br /&gt;
*=DEBUG&amp;lt;off|on|0|1|2|3|4|5&amp;gt;= Der DEBUG Befehl kommt dann zum Einsatz, sobald sie ihr Mapfile speziell testen möchten. So geben die einzelnen Level detailierte Antworten,zum Beispiel über die Darstellungsdauer des einzelnen Layer. Um den DEBUG Parameter verwendeen zu können, muss im Vorfeld im oberen MAP-Teil ein MS_ERRORFILE definiert werden, über dem die Ausgabedatei bestimmt wird. Näheres dazu finden sie im Kapitel 12 Logging.&lt;br /&gt;
*=DUMP&amp;lt;true|false&amp;gt;= Ist default mäßig auf =false=, sollten sie später mit WMS GetFeatureInfo arbeiten empfiehlt es sich, diesen Parameter auf =true= zusetzen, damit der MapServer die Anfrage bearbeiten kann. Die Antwort liefert der MapServer als GML Datei.&lt;br /&gt;
*=FILTER&amp;lt;string&amp;gt;= &lt;br /&gt;
*=FILTERITEM&amp;lt;attribute&amp;gt;= &lt;br /&gt;
*=LABELCACHE&amp;lt;on|off&amp;gt;= &lt;br /&gt;
*=LABELITEM&amp;lt;colname&amp;gt;= Mit diesem Befehl, lassen sich ihre Vektordaten beschriften (labeln), hierfür geben sie die Spalte, aus der gewünschten Datenquelle, an in der sich der gewünschte, darzustellende Zeichensatz befindet. Zur Beschriftung mit Inhalten aus mehreren Datenspalten kann der TEXT-Eintrag in der CLASS genutzt werden in der Form: TEXT ([colname 1], [colname 2]). Möglich ist damit auch, dynamische Einträge aus den Tabellenspalten mit fixen Textbestandteilen zu mischen. In diesen Fällen kann LABELITEM entfallen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Bsp. 1: Mischung aus zwei Tabellenspalten&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT ([stadtteil]-[stadtviertel])&lt;br /&gt;
  END&lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
Bsp. 2: Mischung aus einer Tabellenspalte und fixen Text (''GK:'')&lt;br /&gt;
&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    TEXT (GK:[gk-zone])&lt;br /&gt;
  END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*=OPACITY&amp;lt;integer|alpha&amp;gt;= Definiert die Tranpsarents eines Layers, hierbei können sie mit zwei unterschiedlichen Operanten arbeiten. Die am häufigsten verwendete Methode ist die Angabe des Wertebereichs von 0 bis 100 als Integerzahl, wobei 100 den Layer komplett transparent darstellt. Die zweite Möglichkeit kommt eher selten zum Einsatz, dabei wird...&lt;br /&gt;
*=PROCESSING&amp;lt;string&amp;gt;= &lt;br /&gt;
*=REQUIRES&amp;lt;expression&amp;gt;=&lt;br /&gt;
*=SIZEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles&amp;gt;=&lt;br /&gt;
*=STYLEITEM&amp;lt;attribute]&amp;gt;=&lt;br /&gt;
*=TILEINDEX&amp;lt;filename|layername&amp;gt;=&lt;br /&gt;
*=TILEITEM&amp;lt;attribute&amp;gt;=&lt;br /&gt;
*=TOLERANCE&amp;lt;double&amp;gt;=&lt;br /&gt;
*=TOLERANCEUNITS&amp;lt;pixels|feet|inches|kilometers|meters|miles|dd&amp;gt;=&lt;br /&gt;
*=UNITS&amp;lt;feet|inches|kilometers|meters|miles|dd|pixels|percentages&amp;gt;= &lt;br /&gt;
*=HEADER&amp;lt;filename&amp;gt;= &lt;br /&gt;
*=FOOTER&amp;lt;filename&amp;gt;= &lt;br /&gt;
&lt;br /&gt;
=Classes=\index{Classes}\index{Klassen}\index{Mapfile!Classes}&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie auf alle Fälle die Hinweise in Abschnitt~6, insbesondere, wenn Sie bisher älteren MapServer-Versionen als 4.0 gearbeitet haben.&lt;br /&gt;
&lt;br /&gt;
Classes residieren ausschließlich innerhalb eines Layers. Sie definieren, wie die Daten innerhalb eines Layers tatsächlich dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
Zur Illustration ein erstes kleines Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Vektorlayer gibt es lediglich eine einzige Class, was bedeutet, dass alle Shapes aus dem Shapefile auf die gleiche Weise dargestellt werden. In diesem Fall sind sie blau eingefärbt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie zur Einfärbung von Linien und Punkten das Attribut =COLOR=  benutzen müssen, wohingegen dieser Wert bei Polygonen die Füllfarbe bezeichnet. Der Rand des Polygons wird durch =OUTLINECOLOR=  angesprochen.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Datenabhängiges Einfärben}&lt;br /&gt;
&lt;br /&gt;
Wozu aber nun Classes einführen, wenn man diese Angaben auch direkt in den Layer schreiben könnte? Weil man durch Classes themenbezogene Darstellungen erreichen kann. Sehen wir uns das folgende Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;fluesse&amp;quot;&lt;br /&gt;
  DATA &amp;quot;shapes/fluesse&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION &amp;quot;Wolga&amp;quot;&lt;br /&gt;
    COLOR 255 31 31&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 31 31 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir sehen zuerst ein neues Schlüsselwort, =CLASSITEM= . Die Zeichenkette dahinter benennt die Spalte in der ''.dbf'' -Tabelle, anhand derer wir im folgenden filtern wollen. Alle Angaben in den Classes, die sich in diesem Layer befinden, orientieren sich an der Spalte mit diesem Namen.&lt;br /&gt;
&lt;br /&gt;
In der ersten Class befindet sich eine =EXPRESSION= , ein Ausdruck. Damit ein Feature mit den Angaben in dieser Klasse dargestellt wird, muß das =CLASSITEM=  auf diesen Ausdruck passen. Oder für das Beispiel: die erste Klasse findet Anwendung auf alle Shapes im Shapefile, deren NAME in der ''.dbf'' -Datei 'Wolga' lautet.&lt;br /&gt;
&lt;br /&gt;
Die Classes in einem Layer werden von oben nach unten abgearbeitet, und die erste passende Class wird zur Darstellung verwendet.&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck in der letzten Class in diesem Beispiel bedeutet übrigens 'alle Zeichen'. Jeder mögliche Inhalt einer Spalte passt auf diesen Ausdruck. Es ergibt Sinn, eine solche 'Catch all'-Class anzulegen, um allen Features ein Standardaussehen zu verpassen, die nicht von einer der vorherigen Class abgedeckt worden sind. Eine Erklärung der möglichen Ausdrücke erfolgt im nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Mögliche Ausdrücke}&lt;br /&gt;
&lt;br /&gt;
Es gibt drei verschiedene Weisen, eine =EXPRESSION=  zu formulieren: mit Zeichenketten, mit regulären Ausdrücken und schließlich mit logischen Ausdrücken.&lt;br /&gt;
&lt;br /&gt;
Zeichenketten sind bereits im obigen Beispiel zu sehen gewesen. Die Einträge in den Spalten der ''.dbf'' -Datei werden darauf geprüft, ob sie ''genau''  diesen Wert enthalten. Diese Art von =EXPRESSION=  ist durch den MapServer am schnellsten abzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Logische Ausdrücke sind Ausdrücke, die durch logische Operatoren gebildet werden können. Dazu gehören Konstrukte für gleich, ungleich, größer als, kleiner als und so weiter; darüber hinaus und, oder, nicht, und alle Kombinationen, die sich daraus ergeben. Dabei können weitere Spaltennamen in der .dbf-Datei referenziert werden. Als Beispiel ein Ausschnitt aus einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASSITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Wolga&amp;quot; and [SIZE] &amp;lt; 10)&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /^A.+e&amp;lt;math&amp;gt;/&lt;br /&gt;
  COLOR 0 0 255&lt;br /&gt;
END&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION /./&lt;br /&gt;
  OUTLINECOLOR 128 128 128&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die erste Klasse findet Anwendung auf alle Shapes, deren Spalte =NAME=  im .dbf-File den Eintrag ''Wolga''  haben und gleichzeitig einen kleineren Wert als ''10''  in der Spalte =SIZE= .&lt;br /&gt;
&lt;br /&gt;
Obwohl diese Ausdrücke schon eine Menge Flexibilität bieten, kann man noch einen Schritt weiter gehen, wie man in der zweiten Klasse sehen kann. Die Art des dortigen Ausdrucks ist Informatikern als sogenannter regulärer Ausdruck bekannt. Der Ausdruck passt auf alle Einträge in der =NAME= -Spalte, auf die folgendes zutrifft: der erste Buchstabe ist ein großes ''A'' , das von einer beliebigen Anzahl beliebiger Zeichen (mindestens jedoch einem) gefolgt wird, abgeschlossen durch ein kleines ''e'' .&lt;br /&gt;
&lt;br /&gt;
Die letzte Regel zeigt ebenfalls einen regulären Ausdruck. Er passt auf jedes beliebige Zeichen. Da die Classes von oben nach unten auf der Suche nach der ersten passenden Regel für ein Feature abgesucht werden, handelt es sich um eine sogenannte ''catch all'' -Regel, die auf alles zutrifft, was nicht vorher schon irgendwo gepasst hat.&lt;br /&gt;
&lt;br /&gt;
Reguläre Ausdrücke sind ein ungemein mächtiges Werkzeug, das jedoch etwas Mühe zu Lernen erfordern kann. MapServer verwendet POSIX-konforme reguläre Ausdrücke, die auf jedem Unix-System in einer =man= -Page~[[man:7:regex]] erklärt werden.&lt;br /&gt;
&lt;br /&gt;
=Styles=(6)\index{Styles}\index{Mapfile!Styles}&lt;br /&gt;
&lt;br /&gt;
Mit MapServer 4.0 ist eine weitere Art eingeführt worden, die Darstellung eines Layers zu notieren. Um genau zu sein, sollte diese Art langsam aber sicher bevorzugt werden, zumal sie auch zusätzliche Vorteile bietet.&lt;br /&gt;
&lt;br /&gt;
Aber zunächst sollen Sie natürlich erfahren, um was es geht. MapServer kennt ein neues Objekt, also eine Sektion, mit dem Namen =STYLE= . Diese Sektion trit nur innerhalb von Classes auf und wird selbstverständlich jeweils mit einem =END=  abgeschlossen. Das ganze soll den Zweck haben, den gestalterischen Part einer Class vom logischen zu trennen. Anstatt also folgendes zu notieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
  COLOR 32 64 218&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
würden Sie in Zukunft folgendes schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  EXPRESSION ([NAME] eq &amp;quot;Havel&amp;quot; and [SIZE] &amp;gt; 20)&lt;br /&gt;
  STYLE&lt;br /&gt;
    SYMBOL &amp;quot;punkt&amp;quot;&lt;br /&gt;
    COLOR 32 64 218&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Moment können Sie noch beides verwenden. Im Sinne einer sauberen Arbeitsweise sollte Sie allerdings dazu übergehen, Styles zu benutzen und die Parameter, die für die Darstellung zuständig sind, nicht mehr direkt in den Classes zu notieren.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter wandern in die Style-Sektion einer Class:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS=   &lt;br /&gt;
*=BACKGROUNDCOLOR=   &lt;br /&gt;
*=COLOR=   &lt;br /&gt;
*=MAXSIZE=   &lt;br /&gt;
*=MINSIZE=   &lt;br /&gt;
*=OFFSET=   &lt;br /&gt;
*=OUTLINECOLOR=   &lt;br /&gt;
*=SIZE=   &lt;br /&gt;
*=SYMBOL=   &lt;br /&gt;
&lt;br /&gt;
Die Notierung der Parameter erfolgt wie weiter vorne ab Seite~\pageref{text:mapfile:class:parameters} beschrieben.&lt;br /&gt;
&lt;br /&gt;
Warum sollte man das haben wollen? Es soll in Zukunft möglich sein, Styles mit Namen zu versehen, und dadurch Styles im gesamten Mapfile durch eben ihren Namen zu referenzieren. Dadurch kann bei umfangreichen Mapfiles  einiges an Schreibarbeit eingespart werden. Insbesondere wird aber zukünftig Arbeit einsparen, weil Sie dann nur noch Styles von einem Mapfile ins andere Kopieren müssen, ohne auch noch an einer Class herumhantieren zu müssen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann man mehrere Styles in einer Class haben, sie werden der Reihe nach von oben nach unten ausgewertet; dabei wird, wie schon bei den Layern im Mapfile, der oberste Style zuerst gezeichnet. Dadurch ist es endlich möglich, mehr als die bisherigen 2 Symbole übereinander zu legen, wie es bisher mit =SYMBOL=  und =OVERLAYSYMBOL=  geschehen ist.&lt;br /&gt;
&lt;br /&gt;
Außerdem -- dieser Teil ist allerdings reine Spekulation des Autors -- dürfte eine Abspaltung des darstellenden Teils einer Class die Implementierung der so genannten ''styled layer descriptors''  vereinfachen, einem OGC-Standard~[[pdf:spec:sld10]], mit dem sich die Darstellung von Kartenfeatures über URL-Parameter beeinflussen läßt.&lt;br /&gt;
&lt;br /&gt;
=Rasterdaten=(7)&lt;br /&gt;
\index{Rasterdaten}\index{Mapfile!Rasterdaten}&lt;br /&gt;
&lt;br /&gt;
Rasterdaten sind alle Arten von Daten, deren Dimensionen in Länge und Breite in Pixeln gemessen werden kann, vulgo: Bildformate. Die Bildformate, die von MapServer unterstützt werden, müssen in zwei Kategorien eingeteilt werden: die von der Software lesbaren (Input) und die Ausgabeformate (Output).&lt;br /&gt;
&lt;br /&gt;
Als Ausgabe liefert MapServer Bilder, die von Webbrowsern darstellbar sind. Da sich MapServer dabei auf die Grafikbibliothek GD stützt, ist er auf deren Fähigkeiten angewiesen. &lt;br /&gt;
&lt;br /&gt;
Ein typischer Rasterlayer wird im Mapfile etwa auf folgende Art angelegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER &lt;br /&gt;
  NAME &amp;quot;brandenburg_luftbild&amp;quot;&lt;br /&gt;
  DATA &amp;quot;bilder/brandenburg.tif&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird ein ''tiff'' -Bild eingebunden, das anscheinend ein Luftbild der Region Brandenburg zum Inhalt hat. Der =TYPE=  des Layers ist als =RASTER=  angegeben.&lt;br /&gt;
&lt;br /&gt;
Welche Formate eingelesen werden können, ist im wesentlichen eine Frage, die bei der Konfiguration noch vor der Kompilierung der Software geklärt wird. Einige Formate können dabei als eingebaut angesehen werden, indem der MapServer direkt auf die entsprechenden Bibliotheken zugreift. Andere Formate werden über die Rasterbibliothek GDAL gehandhabt.&lt;br /&gt;
&lt;br /&gt;
Welche Formate Ihr MapServer handhaben kann, können Sie durch das Ausführen des CGI-Binaries auf der Kommandozeile mit dem Kommandozeilenschalter&lt;br /&gt;
''-v''   herausfinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
thfischer@grobi # ./mapserv -v&lt;br /&gt;
MapServer version 4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF&lt;br /&gt;
OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER&lt;br /&gt;
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT&lt;br /&gt;
INPUT=EPPL7 INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel sehen wir =.jpeg=  als (lesend) unterstütztes Rasterformate. Weitere Formate können durch Verwendung der GDAL-Schnittstelle angesprochen werden, insbesondere findet hier das Lesen von =.tif= -Bildern über GDAL statt. Mehr zu diesen Bibliotheken finden Sie weiter hinten im Buch.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass es für Rasterdaten keine Queries auf den Layer geben kann, da mit den gängigen Rasterformaten keine Metadaten gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==Bildkataloge==(8)&lt;br /&gt;
\index{Rasterdaten!Kataloge}\index{Bildkataloge}&lt;br /&gt;
&lt;br /&gt;
Bilddaten können sehr schnell sehr groß werden. Detaillierte Rasterbilder können viele Megabyte, wenn nicht gar Gigabyte groß werden. Solche Datenmengen sind nur schwierig zu handhaben, sowohl für den MapServer als auch, was die Verwaltung angeht. Um die Verarbeitung zu beschleunigen und die Handhabung zu vereinfachen, kann man sich so genannter Bildkataloge bedienen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren kann es natürlich passieren, dass man seine Daten gleich in mehreren Bildern bekommt, aber sicherlich nicht für jedes Bild einen eigenen Layer im Mapfile anlegen möchte. Man könnte die Layer natürlich mittels =GROUP=  zusammenfassen; aber man müßte eben immer noch alle Layer ins Mapfile eintragen.&lt;br /&gt;
&lt;br /&gt;
Das Format von MapServer-Bildkatalogen verwendet keinen verbreiteten Standard, der dazu führen würde, dass Sie die Bildkataloge auch mit anderen Programmen einlesen könnten. Allerdings verläßt sich MapServer auf standardisierte Datenformate, sodass eine Konvertierung von dieser Seite aus keine Schwierigkeiten bereiten sollte.&lt;br /&gt;
&lt;br /&gt;
Dabei werden alle Bilder (sie müssen mit Worldfiles georeferenziert sein) über ein Shapefile verortet. Das Shapefile erhält dabei die Koordinaten der einzelnen Bilder, die ''.dbf'' -Datei der Reihe nach die dazugehörigen Dateinamen der Bilder.&lt;br /&gt;
&lt;br /&gt;
Die Notation solcher Kataloge im Mapfile erfolgt folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;luftbild&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;luftbildshape&amp;quot;&lt;br /&gt;
  TILEITEM &amp;quot;IMAGEFILENAME&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel trägt das Katalog-Shapefile den Namen =luftbildshape= . Mit =TILEITEM=  gibt man an, wie die Spalte in der ''.dbf'' -Datei heißt, die die Dateinamen der Rasterbilder trägt.&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von Bildkatalogen muß durch zusätzliche Software geschehen. Die Bibliothek GDAL bringt dafür ein Werkzeug namens =gdaltindex=  mit -- siehe Seite~\pageref{text:tools:gdaltindex}&lt;br /&gt;
&lt;br /&gt;
Durch den Aufbau mittels eines Shapefiles lassen sich die einzelnen Kacheln selber übrigens sehr schön visualisieren, indem man das betreffende Shape als Layer einbindet.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten klassifizieren==&lt;br /&gt;
&lt;br /&gt;
Rasterdaten können, ähnlich wie Vektordaten, klassifiziert werden. Dabei werden alle Pixel einer bestimmten Farbe (oder einer bestimmten Menge von Farben) auf eine andere Farbe abgebildet. Das macht man gerne bei 1-Bit-Bildern. Diese bestehen nur aus zwei Farben (also schwarz und weiß). Man färbt dann alle schwarzen Pixel in der gewählten Farbe ein, und schaltet dann die weißen Pixel für gewöhnlich transparent. Auf diese Weise lassen sich viele solcher Bilder in Schichten übereinander legen.&lt;br /&gt;
&lt;br /&gt;
Es können aber auch Bilder mit 256 Farben klassifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Schauen wir uns ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;grundwasser&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  CLASSITEM &amp;quot;[pixel]&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;lt; 128)&lt;br /&gt;
    COLOR 255 0 0&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION ([pixel] &amp;gt;= 128)&lt;br /&gt;
    COLOR 0 0 255&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das =CLASSITEM= , nach dem wir filtern möchten, trägt den Namen =pixel=  und repräsentiert die Nummer der Farbe in der Farbpalette des Bildes. Das funktioniert im Moment übrigens nur bei GD-Ausgabetreibern korrekt; der GDAL-Treiber\footnote{Zu Ausgabeformaten und -treibern siehe auch Seite~\pageref{text:mapfile:ausgabeformate}.} biegt vor der Bearbeitung des Bildes die Farbpaletten um, sodass man sich nicht auf die Position in der Farbpalette verlassen kann.&lt;br /&gt;
&lt;br /&gt;
Die erste Class verleiht nun den ersten 128 Farben in der Farbpalette des Bildes ein grelles Rot, alle anderen Pixel werden durch die zweite Class blau dargestellt.&lt;br /&gt;
&lt;br /&gt;
FIXME: ist das analog für truecolor-bilder etc.?&lt;br /&gt;
&lt;br /&gt;
==Umprojizieren von Rasterdaten==&lt;br /&gt;
&lt;br /&gt;
Der Gedanke läuft einem zuwider, wenn man sich die Mathematik klar macht. Man betrachte ein 4000 mal 4000 großes Tiff-Bild. Wenn man dieses Bild komplett umprojizieren möchte, müssen also 16 Millionen Pixel darauf geprüft werden, ob sie im neuen Zielbild liegen. Und wenn wir nun annehmen, dass wir 16 mal 16 solcher Kacheln haben, landen wir bei über 4 Milliarden Pixeln. Dass diese Berechnung eine Weile dauert, ist auf den ersten Blick ersichtlich.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es jedoch einmal ausprobieren, werden Sie erstaunt sein, wie schnell MapServer Ihnen eine umprojizierte Karte liefert. Leider immer noch nicht schnell genug, wie man es im Dauerbetrieb, beispielsweise auf einer Website, haben will. Sie können sehr wohl mit der Geschwindigkeit vor Ihren Freunden angeben. Für den Dauerbetrieb lohnt es sich aber, die Projektion für Ihre Daten vorher zu machen.&lt;br /&gt;
&lt;br /&gt;
Gleiche Überlegungen gelten übrigens auch für verschiedene Zoomstufen. Es lohnt sich durchaus, im Vorhinein zu überlegen, welche Zoomstufen am häufigsten zu sehen sein werden, um dann mit =MINSCALE=  und =MAXSCALE=  für diese Stufen verschiedene Datensätze anzuzeigen. Weitere Überlegungen zur Performance von MapServer-Anwendungen finden Sie ab Seite~\pageref{anhang:performance}.&lt;br /&gt;
&lt;br /&gt;
==Rasterdaten mit GDAL==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{gtopo30}{Die GTOPO30-Daten, hier ein Ausschnitt des Kanals zwischen Frankreich und Großbritannien.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Die Bibliothek GDAL ist für das Einlesen von Rasterdaten in MapServer zuständig, die über die 'herkömmlichen' Formate wie TIFF, JPEG, PNG und so weiter hinausgehen. Eine Liste von unterstützten Formaten finden Sie auf der GDAL-Website~[[http:website:gdal]]. Für diverse Formate müssen Sie unter Umständen die eine oder andere Zusatzbibliothek installiert haben. Bei Fragen oder Problemen hilft entweder ebenfalls die GDAL-Site weiter, oder eine Anfrage auf der MapServer-Mailingliste.&lt;br /&gt;
&lt;br /&gt;
Die Notation von GDAL-gelesenen Rasterdaten weicht glücklicherweise überhaupt nicht von der von herkömmlichen Rasterdaten ab. Als Beispiel sollen hier die GTOPO30-Daten herhalten, die man sich von~[[ftp:gtopo30]] herunterladen kann\footnote{Achtung, falls Sie es auf den kompletten Datensatz für die ganze Welt abgesehen haben sollten: vollständig entpackt handelt es sich um 2,1 GB Daten. Beachten Sie bitte, dass es sich dabei um =Textdateien=  handelt, die Bearbeitung also durchaus zeitintensiv ist.}.&lt;br /&gt;
&lt;br /&gt;
Interessant sind für die Notation die Dateien mit der Endung =.DEM= . Die Abkürzung steht für ''digital elevation model'' , also für digitales Höhenmodell.&lt;br /&gt;
&lt;br /&gt;
Sie können diese Daten in ein Unterverzeichnis entpacken -- nennen wir es =gtopo30=  -- und dann ''gdaltindex''  für das Erzeugen eines Bildkatalogs aufrufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
# gdaltindex gtopo30.shp gtopo30/*.DEM&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haben Sie das getan, können Sie sich einfach einen Layer wie folgt konstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TILEINDEX &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und damit sind Sie dann auch schon fertig! Das Ergebnis sind dann beispielsweise aus wie in Abbildung~\ref{gtopo30}. Das DEM-Format wird behandelt wie jedes andere Rasterformat auch. Dem entsprechend können Sie eine einzelne dieser DEM-Dateien auch wie gewohnt folgendermaßen einbinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gtopo30&amp;quot;&lt;br /&gt;
  TYPE RASTER&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gtopo30/W180S60.DEM&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Vektordaten=&lt;br /&gt;
\index{Vektordaten}&lt;br /&gt;
&lt;br /&gt;
In seinen 'Jugendzeiten' war MapServer im wesentlichen darauf ausgelegt, Shapefiles darzustellen. Das macht sich insbesondere bei der Notation im Mapfile bemerkbar, wo bei Vektordaten einige Shapfile-spezifische Termini verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zuerst ein Beispiel für Vektordaten in einem Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gruenflaechen&amp;quot;&lt;br /&gt;
  TYPE POLYGON&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  DATA &amp;quot;gruenflaechen_0323333&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    EXPRESSION /./&lt;br /&gt;
    COLOR 255 240 128&lt;br /&gt;
    OUTLINECOLOR 128 120 64&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Vektorlayers kann =POINT= , =LINE=  oder =POLYGON=  sein. Beachten Sie dabei, dass die beiden letztgenannten intern im wesentlichen gleich sind und daher in einigen Fällen austauschbar sind.&lt;br /&gt;
&lt;br /&gt;
=DATA=  verweist in diesem Fall auf ein Shapefile mit dem angegebenen Namen. Dieser Name ist relativ zum =SHAPEPATH=  im Header des Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Das war auch schon alles, was es zur Notation von Shapefile-Layern im Mapfile zu sagen gibt. MapServer ist in der Lage, über Zusatzbibliotheken weitere Vektorformate zusätzliche zu Shapefiles einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==Indizes für Shapefiles==\index{Index}\index{Index!Shapefiles}(9)&lt;br /&gt;
&lt;br /&gt;
Mit sogenannten Quadtree-Indizes läßt sich die Bearbeitung von Shapefiles erheblich beschleunigen. Wie solche Indizes für den MapServer erstellt werden, erfahren Sie auf Seite~\pageref{text:tools:shptree}, wo das Werkzeug =shptree=  vorgestellt wird. Hier soll nur kurz die dahinter stehende Idee erläutert werden.&lt;br /&gt;
&lt;br /&gt;
In einem Shapfile, das beispielsweise 100 Shapes hat, muß für einen gegebenen Ausschnitt geprüft werden, ob das Shape ganz oder in Teilen in diesem Ausschnitt liegt und demnach angezeigt werden soll. Das geschieht über die Bounding Box eines Shapes, die mit im Shapefile gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
Ein Quadtree-Index folgt dem Gedanken, die Fläche des Shapefiles in vier Teile einzuteilen, und die darin liegenden Shapes in einem Index festzuhalten. Bei einem Zugriff wird zuerst die Fläche gesucht, in der der Ausschnitt liegt, und somit die Anzahl der zu prüfenden Shapes vermindert.&lt;br /&gt;
&lt;br /&gt;
Die einzelnen Flächen lassen sich danach noch einmal in vier Unterflächen aufteilen (und diese wiederum in vier Unterflächen, und so weiter), sodass bei der Darstellung eine baumartige Struktur entsteht.&lt;br /&gt;
&lt;br /&gt;
Die Größe und Lage der einzelnen Flächen muß übrigens nicht genau jeweils ein Viertel der größeren Fläche einnehmen. Die einzelnen Flächen werden nach Anzahl der darin liegenden Shapes gewichtet.&lt;br /&gt;
&lt;br /&gt;
==Graticule-Layer==\index{Graticules}\index{Grids}(10)&lt;br /&gt;
&lt;br /&gt;
Ein Gitternetz kann in einer Karte zur Orientierung wertvoll sein. Leider hat man nicht immer ein entsprechendes Shapefile zur Hand. Abhilfe schaffen sogenannte Graticule-Layer, mit denen sich ein solches Gitternetz einfach definieren läßt.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir einen solchen Layer anhand eines Beispiels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gitternetz&amp;quot;&lt;br /&gt;
  TYPE LINE&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  GRID&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    COLOR 0 0 0&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE TINY&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
  PROJECTION&lt;br /&gt;
    &amp;quot;init=epsg:4326&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwei Dinge fallen sofort auf. Zuerst einmal sieht man keine =DATA= -Angabe. Brauchen wir an dieser Stelle auch gar nicht, da unser Gitter für jeden Kartenaufruf dynamisch generiert werden soll.&lt;br /&gt;
&lt;br /&gt;
Außerdem findet man eine neue Sektion =GRID= . In dieser Sektion werden die Eigenschaften des Gitters gesetzt.&lt;br /&gt;
&lt;br /&gt;
Der Typ eines Gitterlayers ist =LINE= . Die Gestaltung des Gitters wird wie gewohnt in einer Class vorgenommen, und das Gitter kann beschriftet werden. Die Labels für die Beschriftung erscheinen immer an allen vier Seiten einer Karte. Für TrueType-Fonts empfiehlt sich eine sehr kleine Schriftgröße, da diese Beschriftung sonst sehr schnell aufdringlich wirken kann.&lt;br /&gt;
&lt;br /&gt;
Der =PROJECTION= -Block gibt die Projektion des Gitters an. Der Layer wird dann so behandelt, als würde es sich bei der Datenquelle um ein Shapefile handeln, das in eben dieser Projektion vorliegt. Ohne Projektionsblock erhalten Sie ein einfaches rechteckiges Gitter; mit Projektion ist das Gitter natürlich entsprechend verzerrt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass die Beschriftung des Gitters immer im Koordinatensystem der Quellprojektion erfolgt. Wenn Sie also beispielsweise den EPSG-Code 4326 als Projektion für Ihren Gitterlayer angeben, so wird dieses Gitter in Gradangaben beschriftet werden, selbst wenn Sie eine Karte mit Gauss-Krüger-Koordinaten erzeugen.&lt;br /&gt;
&lt;br /&gt;
Innerhalb des =GRID= -Blocks können Sie die folgenden Angaben machen, die allesamt nur eine einzelne Zahl als Parameter erwarten:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=MINSUBDIVIDE=  und =MAXSUBDIVIDE= : Jede der Kurven (Linien), aus denen das Gitter besteht, wird als separate Linie behandelt und besteht somit aus einzelnen Punkten. Je mehr Punkte für eine Linie gezeichnet werden müssen, desto mehr Prozessorzeit kostet das offensichtlich. Mit diesen beiden Parametern können Sie festlegen, aus wievielen Punkte eine Linie minimal beziehungsweise maximal zusammengesetzt sein darf. Sind die beiden Werte gleich, bestehen die Linien immer aus genausovielen Punkten wie angegeben.    &lt;br /&gt;
*=MININTERVAL=  und =MAXINTERVAL= : Mit diesen beiden Parameter können Sie ein minimales bzw. ein maximales Intervall zwischen zwei Kurven des Gitters angeben. Die Angabe wird im Koordinatensystem des Gitters gemacht.     &lt;br /&gt;
*=MINARCS=  und =MAXARCS= : Setzt die minimale bzw. maximale Anzahl von Kurven pro Achse.    Beachten Sie bitte, dass bei diesen beiden Parametern und den beiden vorhergehenden ''versucht''  wird, den Vorgaben nachzukommen. Sollten die von Ihnen notierten Werte nicht zum gewünschten Ergebnis führen, sollten Sie ein wenig experimentieren, um ein Gefühl dafür zu bekommen, wie sich der Code bei verschiedenen Werten verhält.  &lt;br /&gt;
&lt;br /&gt;
=Projektionen=(11)&lt;br /&gt;
\index{Projektion}\index{Mapfile!Projektion}(12)&lt;br /&gt;
&lt;br /&gt;
Zuerst die These: die Erde ist eine Kugel. Diese Kugel muß für eine Karte auf eine Ebene abgebildet werden. Das gilt für eine Papierkarte ebenso wie für einen Computerbildschirm. Wenn man jetzt bedenkt, dass es viele verschiedene Ideen gibt, Abbildungen von der Kugel auf die Ebene vorzunehmen, und wenn man dann noch einwirft, dass die Erde ja eigentlich gar keine richtige Kugel ist -- dann ist man in der Welt der Projektionen angekommen, die ebenso faszinierend wie enervierend sein kann.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.75}{projektion}{Ein und dieselbe Datenquelle in zwei verschiedenen Projektionen. Links EPSG:4326, rechts EPSG:31464.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Der Effekt, um den es geht, ist in Abbildung~\ref{projektion} zu sehen. Die rechte Darstellung der Datenquelle verwendet die Geo-Koordinaten der Bundeslandgrenzen (Ellipsoid WGS84). Die rechte Darstellung entspricht einer Projektion in die Ebene nach der Gauss-Krüger-Methode, hier im vierten Meridianstreifen.&lt;br /&gt;
&lt;br /&gt;
Der MapServer verwendet für Projektionen eine eigene Bibliothek (''proj.4'' ) die von Haus aus bereits viele Projektionen kennt. Diese Bibliothek unterstützt aber auch EPSG-Codes~[[http:website:epsg]], die seit Einführung der OGC-Konformität die gängige Art und Weise darstellen, Projektionen im Mapfile zu notieren.&lt;br /&gt;
&lt;br /&gt;
Projektionen interessieren an zwei Stellen: einmal bei der Frage, in welchen Projektionen die Daten vorliegen, und in welcher Projektion die fertige Karte dargestellt werden soll. MapServer ist in der Lage, die Projektion von Vektordaten 'on the fly' vorzunehmen. Dabei können die Daten verschiedener Layer durchaus verschiedener Projektion sein. Mit Unterstützung der Bibliothek GDAL ist MapServer auch in der Lage, Rasterdaten umzuprojizieren; die benötigte Rechenleistung dafür ist jedoch beträchtlich, da in einem Rasterbild jeder einzelne Punkt umprojiziert werden muß.&lt;br /&gt;
&lt;br /&gt;
Mehr zur Bibliothek GDAL erfahren Sie in Anhang~\ref{anhang:formate}, in dem die vom MapServer unterstützten Formate vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Projektionen sind, wie bereits angemerkt, an zwei Stellen von Bedeutung: erstens wenn festgestellt werden soll, in welcher Projektion bestimmte Daten vorliegen, zweitens bei der Frage, in welcher Projektion die Karte ausgeliefert werden soll.&lt;br /&gt;
&lt;br /&gt;
Dabei können die Projektionen, in denen die Daten vorliegen, auf Layer-Ebene zugewiesen werden. Jeder Layer kann also in einer eigenen Projektion vorliegen. MapServer ist in der Lage, Vektorlayer auf Anfrage umzuprojizieren. Unter Verwendung des Bibliothek GDAL funktioniert das auch für Rasterdaten. Das Umprojizieren von Rasterdaten ist jedoch derart rechenaufwendig, dass man es in den meisten Fällen vermeiden will.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabeprojektion muß verständlicherweise einheitlich sein, denn die fertige Karte kann schließlich nur in einer bestimmten Projektion vorliegen. Eine Ausnahme bildet ein OGC-konformer MapServer, der verschiedene Projektionen nach außen anbieten und über einen URL-Parameter aufgefordert werden kann, eine dieser Projektionen als Ergebnis zu liefern.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Projektionen geschieht über eine eigene Sektion mit dem Namen =PROJECTION= . In dieser Sektion können Projektionen entweder als eine Liste von Parametern für die Projektionsbibliothek proj.4 eingetragen werden, oder mit EPSG-Codes.&lt;br /&gt;
&lt;br /&gt;
Das erste Beispiel zeigt die 'klassische' Notation anhand der Projektionsbibliothek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=utm&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=GRS80&amp;quot;&lt;br /&gt;
  &amp;quot;zone=15&amp;quot;&lt;br /&gt;
  &amp;quot;north&amp;quot;&lt;br /&gt;
  &amp;quot;no_defs&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Art der möglichen Parameter für die Projektionsbibliothek proj.4 entnehmen Sie bitte der Dokumentation dieser Software~[[http:website:libproj]].&lt;br /&gt;
&lt;br /&gt;
Die zweite Möglichkeit erschließt sich durch EPSG-Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
 &amp;quot;init=epsg:12345&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
12345 ersetzen Sie an dieser Stelle selbstverständlich durch den gewünschten EPSG-Code. Intern greift die Projektionsbibliothek an dieser Stelle übrigens auf eine Tabelle zu, die diese Codes dann auf die &amp;quot;`Original&amp;quot;'-Parameter abbildet. Achten Sie unbedingt darauf, =epsg=  tatsächlich in Kleinbuchstaben zu notieren. Unter Windows ist das nicht relevant; entwickeln Sie jedoch unter einem anderen System, oder soll Ihre Anwendung portierbar sein, ist das wichtig.&lt;br /&gt;
&lt;br /&gt;
Die Sektion =PROJECTION=  kommt für die gesamte Karte nach dem Header im Mapfile zur Anwendung; für die Layer hat die Sektion natürlich innerhalb der =LAYER= -Sektion zu stehen, allerdings außerhalb etwaiger =CLASS= es, =LABEL= s und allem Anderen, das eine eigene Sektion einleitet.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Hinweis}(13)&lt;br /&gt;
&lt;br /&gt;
Man möchte eigentlich meinen, dass die EPSG-Codes in Stein gemeißelt sind. Einmal vergeben, würde sich ein solcher Code nicht mehr ändern.&lt;br /&gt;
&lt;br /&gt;
Leider ist diese Annahme ein Irrtum. Die Vergangenheit hat gezeigt, dass es passieren kann, dass Projektionen um mehrere Stellen in der Liste 'verrutschen' können. Zumindest einige deutsche und teilweise auch österreichische Projektionscodes sind in der Vergangenheit bei einem Versionssprung der Projektionsbibliothek nicht mehr vorhanden gewesen. Die interne Liste für den jeweiligen Release von ''proj.4''  wird scriptgesteuert aus der Access-Tabelle generiert, die man auf der Website der EPSG findet. Änderungen in der Tabelle schlagen also sofort auf die Projektionsbibliothek durch.&lt;br /&gt;
&lt;br /&gt;
Bei unerwarteten Fehlermeldungen nach einem Upgrade der Projektionsbibliothek sollten Sie also prüfen, ob Ihre Projektionscodes noch korrekt sind und diese eventuell anpassen.&lt;br /&gt;
&lt;br /&gt;
Dieses unvorhersehbare Verhalten der EPSG kann natürlich zu haarsträubenden Komplikationen bei kaskadierten WMS-Servern führen, wenn nur einer der Server aktualisiert wird.&lt;br /&gt;
&lt;br /&gt;
==Orthographische Projektion==&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{ortho}{Eine orthographische Projektion stellt die Daten in einem Kreis dar, der einer Aufsicht auf einem Globus ähnlich sieht. Leider ist die Funktion in MapServer noch fehlerhaft.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Eine orthographische Projektion sieht aus wie ein Blick auf einen Globus. Falls die fertige Karte einen großen Teil der Welt abdeckt, sehen Sie die fertige Karte als Kreis. &lt;br /&gt;
&lt;br /&gt;
Das kann schick aussehen, leider hat der Code für diese Projektion in MapServer noch den einen oder anderen Bug, die dann auftreten, sobald Features dargestellt werden sollen, die teilweise hinter dem Horizont verschwinden. Dann versucht MapServer immer noch Linien zu ziehen, die dann quer durch das ganze Bild gehen.&lt;br /&gt;
&lt;br /&gt;
Zum Zeitpunkt der Drucklegung war die Darstellung leider immer noch fehlerhaft. Dennoch soll Ihnen ein Überblick über die Theorie nicht vorenthalten bleiben.&lt;br /&gt;
&lt;br /&gt;
Als Zielprojektion im Kopf des Mapfiles definieren Sie eine orthographische Projektion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
PROJECTION&lt;br /&gt;
  &amp;quot;proj=ortho&amp;quot;&lt;br /&gt;
  &amp;quot;ellps=WGS84&amp;quot;&lt;br /&gt;
  &amp;quot;lat_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;lon_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;x_0=0.0&amp;quot;&lt;br /&gt;
  &amp;quot;y_0=0.0&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind =lat_0=  und =lon_0=  die Koordinaten des Punktes, der als Mittelpunkt in der Karte zu sehen sein soll, in Längen- und Breitenangabe. Das ist sozusagen der Punkt, an dem Sie direkt auf den Globus schauen. Die beiden verbleibenden Parameter sind eine Verschiebung, jeweils ein Modifikator auf den Rechts- und den Hochwert des Punktes.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis sieht dann in etwa so aus, wie Sie es in Abbildung~\ref{ortho} sehen können. Wegen der fehlerhaften Implementation ist die Darstellung von Features, die sich über den Horizont erstrecken, allerdings noch mangelhaft.&lt;br /&gt;
&lt;br /&gt;
Und falls Sie später das Kapitel über MapScript lesen und Anregung für eine Übung suchen sollten, wie wäre es damit: erstellen Sie eine MapScript-Seite, die eine Karte in ortographischer Projektion darstellt. Beim Mausklick in die Karte soll allerdings nicht hinein- oder herausgezoomt werden, sondern eben dieser angeklickte Punkt soll als neuer Bezugspunkt für die Projektion dienen. Der 'Globus' wird also anhand des Klicks 'gedreht'. Viel Spaß dabei =:)= &lt;br /&gt;
&lt;br /&gt;
==Projektionen im realen Einsatz==&lt;br /&gt;
&lt;br /&gt;
Der Autor hat schon von Leuten gehört, die meinten, Projektionen würden die Daten 'verfälschen'. Zu einem gewissen Grad ist das sicherlich richtig; im Grunde genommen handelt es sich aber nur um eine andere Art der Darstellung.&lt;br /&gt;
&lt;br /&gt;
Kartographen sind übrigens nicht die einzigen Menschen, die sich mit Projektionen in die Ebene auseinandersetzen müssen. Eine ganze Industrie in Gestalt der Spiele- und Grafikkartenindustrie lebt mit und von dem Problem, (dreidimensionale) Objekte auf eine plane Fläche (den Computerbildschirm) abzubilden.&lt;br /&gt;
&lt;br /&gt;
Falls Sie in Ihrer Anwendung MapServer Daten ''on the fly''  umprojizieren lassen möchten, sollten Sie sich im Vorhinein über Ihre Zielgruppe Gedanken machen. Menschen könnten es Ihnen durchaus übelnehmen, wenn die Karten im Webbrowser wie in Abbildung~\ref{projektion} links aussehen -- nämlich angeblich 'gequetscht'. Denken Sie immer daran, wass die Benutzer wohl als Darstellung aus ihrem Atlas daheim~[[diercke:2002]] gewohnt sein könnten.&lt;br /&gt;
&lt;br /&gt;
=Schriften=\index{Schriften}\index{Fonts}(14)&lt;br /&gt;
&lt;br /&gt;
MapServer kennt zur Beschriftung von Features zwei Typen von Schriften: Bitmap- und TrueType-Schriften. Während erstere bereits im MapServer `&amp;quot;eingebaut&amp;quot;' sind, sind TrueType-Schriften separate Dateien, die Sie der Anwendung bereitstellen müssen. Hingegen benötigen Bitmap-Schriften keine zusätzliche Vorbereitung, um verwendet zu werden; Sie können direkt mit Abschnitt~15 fortfahren.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Problem mit TrueType-Schriften können lizenzrechtlicher Natur sein. Ob Sie die Schriftdateien, die Sie für den Gebrauch mit beispielsweise Photoshop gekauft haben, einfach so zur Beschriftung und Veröffentlichung von Karten im Internet verwenden dürfen, müssen Sie individuell mit dem Hersteller der Schriften regeln.&lt;br /&gt;
&lt;br /&gt;
Wie die Symbole für eine Karte werden auch die TrueType-Schriftarten in einer separaten Datei deklariert. Anders als die Symbole für ein Mapfile können die Schriften jedoch nicht alternativ direkt in das Mapfile eingetragen werden; sie müssen immer in einer separaten Datei stehen.&lt;br /&gt;
&lt;br /&gt;
Der Verweis auf eine Schriftendatei erfolgt über das Schlüsselwort ''FONTPATH''  im Header des Mapfiles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
FONTPATH &amp;quot;fonts/fonts.list&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Angabe kann sowohl ein absoluter Pfad im System sein, als auch relativ zum Mapfile.&lt;br /&gt;
&lt;br /&gt;
Im Innern ist diese Liste sehr simpel aufgebaut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
arial   arial.ttf&lt;br /&gt;
times   times.ttf&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In jeder Zeile steht zuerst ein Alias, gefolgt von mindestens einer Leerstelle (oder einem Tab) und der Name der .ttf-Datei. Das Alias ist ein Name, der im Folgenden im Mapfile verwendet wird, um auf die Schriftart Bezug zu nehmen.&lt;br /&gt;
&lt;br /&gt;
Für Bitmap-Schriften müssen, wie gesagt, keine solche Vorbereitungen getroffen werden.&lt;br /&gt;
&lt;br /&gt;
=Annotationen=&lt;br /&gt;
\index{Annotationen}&lt;br /&gt;
\index{Beschriftungen}&lt;br /&gt;
(15)&lt;br /&gt;
&lt;br /&gt;
Beschriftungen von Layern sind für MapServer wiederum eigene Layer, mit einem eigenen Typ mit dem Namen =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Die Art der Beschriftung (was wann wie beschriftet werden soll und auf welche Art) wird in den Klassen dieses Layers festgelegt. Dadurch erreicht man eine recht hohe Flexibilität, indem man Beschriftungen von Features unabhängig davon darstellen kann, ob das Feature selber zu sehen ist. Und wenn man beides unter den selben Umständen angezeigt haben möchte, verwendet man für beide Layer einfach die gleiche Klassendefinition.&lt;br /&gt;
&lt;br /&gt;
Für eine Oberfläche zur Navigation in der Karte bedeutet das auf der anderen Seite zusätzliche, unerwünschte Komplexität, da die Beschriftungslayer nun unter Umständen durch den Benutzer als eigene Layer an- und abgewählt werden müssen.&lt;br /&gt;
&lt;br /&gt;
Diesen Umstand kann man auf zwei Wegen umgehen. Eine Methode ist, dem Beschriftungslayer den gleichen Namen zu geben, wie dem Layer, der die Daten anzeigt. Dann werden beide Layer über diesen Namen angesprochen. Der zweite Weg ist, beide Layer zu einer =GROUP=  zusammenzufassen, über deren Namen man auf beide Layer gleichzeitig zugreifen kann. Mehr über das Gruppieren von Layern erfahren Sie ab Seite~\pageref{text:mapfile:layer:group}&lt;br /&gt;
&lt;br /&gt;
Man könnte auch alle Beschriftungen in einer =GROUP=  zusammenfassen, sodass sie sich alle mit einem Mal an- und ausschalten lassen.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich im übrigen nur Vektorlayer beschriften.&lt;br /&gt;
&lt;br /&gt;
Die Notation von Beschriftungslayern sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strasssen_annotation&amp;quot;&lt;br /&gt;
  GROUP &amp;quot;beschriftungen&amp;quot;&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  ...&lt;br /&gt;
  CLASSITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    ...&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE NORMAL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      POSITION CR&lt;br /&gt;
      PARTIALS TRUE&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also diverse Änderungen im Vergleich zu einem dartstellenden Layer vorgenommen. Der Typ des Layers ist =ANNOTATION= .&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort =LABELITEM=  funktioniert so ähnlich wie =CLASSITEM= . Während letzteres jedoch angibt, anhand welcher Spalte in der ''.dbf'' -Datei die nachfolgenden Classes gefiltert werden sollen, definiert =LABELITEM=  die Spalte, aus der der Inhalt für die Beschriftungen geholt werden soll. Auf diese Weise läßt sich also nach einem Kriterium filtern und nach einem anderen beschriften, was die Angelegenheit flexibler gestaltet.&lt;br /&gt;
&lt;br /&gt;
==Die Label-Sektion==\index{Label}\index{Mapfile!Label}&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Definition einer Beschriftung erfolgt dann in den einzelnen Classes. Im obigen Beispiel werden die im MapServer eingebauten Bitmap-Schriften verwendet. Zur genauen Notation von Bitmap- und TrueType-Schriften siehe auch die nächsten beiden Abschnitte.&lt;br /&gt;
&lt;br /&gt;
Wie so häufig kommt erhöhte Flexibilität auch an dieser Stelle auf Kosten größeren Aufwands. Für jede zu beschriftende Klasse muß eine eigene Label-Sektion eingerichtet werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter finden in allen Arten von Labeln Verwendung, unabhängig davon, ob es sich um Bitmap- oder TrueType-Beschriftungen handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Mit dieser Option bekommt das Label eine Hintergrundfarbe verpaßt; man sieht dann ein Rechteck in dieser Farbe, in dem sich dann das Label befindet. Voreinstellung ist gar keine Farbe.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Wirft einen Schatten in der angegebenen Farbe um das eben genannte Rechteck. Voreinstellung ist kein Schattenwurf.  &lt;br /&gt;
*=BACKGROUNDSHADOWCOLORSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Legt den Offset für den genannten Schatten in x- und y-Richtung fest. Voreinstellung in beide Richtungen ist 1.  &lt;br /&gt;
*=BUFFER &amp;lt;integer&amp;gt;=  Definiert einen Abstand, den andere Beschriftungen zu einem Label mindestens haben müssen, um gezeichnet werden zu können. Erhöht die Lesbarkeit bei vielen Beschriftungen, kann aber zu Problemen führen (siehe Abschnitt~16, ''Hinweise'' ).  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der die Schrift gemalt werden soll.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrißarbe für die Schrift.  &lt;br /&gt;
*=FORCE &amp;lt;TRUE|FALSE&amp;gt;=  Erzwingt das Zeichnen einer Beschriftung. Dadurch werden Einträge wie =BUFFER=  ignoriert. Diese Option ist als Vorgabe nicht aktiviert.  &lt;br /&gt;
*=POSITION=   &lt;br /&gt;
*=PARTIALS &amp;lt;TRUE|FALSE&amp;gt;=  Unter Umständen liegen einzelne Features so ungünstig, dass seine Beschriftung nur teilweise sichtbar wäre. Mit =PARTIALS=  wird festgelegt, ob diese teilweise Beschriftungen angezeigt werden sollen.  &lt;br /&gt;
*=WRAP &amp;lt;zeichen&amp;gt;=  Legt ein Zeichen fest, das als Zeilentrenner interpretiert werden soll. Das Ergebsnis sind mehrzeilige Beschriftungen.  &lt;br /&gt;
&lt;br /&gt;
Labels lassen sich außer zur Beschriftung auch bei TrueType-Symbolen verwenden; siehe auch Abschnitt~18&lt;br /&gt;
&lt;br /&gt;
==Bitmap-Schriften==\index{Bitmap-Schriften}&lt;br /&gt;
\index{Beschriftungen!Bitmap}\index{Annotationen!Bitmap}&lt;br /&gt;
&lt;br /&gt;
Bitmap-Schriften skalieren schlecht und sehen, gelinde gesagt, nicht sonderlich gut aus. Sie benötigen jedoch keinen zusätzlichen Aufwand und sind in jeder MapServer-Installation automatisch vorhanden. Auch benötigen sie wesentlich weniger Rechenzeit.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Beschriftung nur um der Beschriftung willen einsetzen möchten und keine besonderen Anforderungen an ihr Aussehen stellen, sind Bitmap-Schriften das, was Sie haben möchten.&lt;br /&gt;
&lt;br /&gt;
Ein =ANNOTATION= -Layer mit Bitmap-Schriften sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE BITMAP&lt;br /&gt;
      SIZE SMALL&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Feature wird hier mit einer kleinen, weiß umrandeten, schwarzen Beschriftung versehen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen sind nur beim Einsatz von Bitmap-Schriften von Belang:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=SIZE &amp;lt;TINY|SMALL|MEDIUM|LARGE|GIANT=  Diese fünf verschiedenen Größen sind fix, und es gibt keine Zwischengrößen. Experimentieren Sie am besten mit allen herum, um ein Gefühl dafür zu kriegen, wie groß sie im Einsatz sind.  &lt;br /&gt;
&lt;br /&gt;
==TrueType-Schriften==\index{TrueType-Schriften}&lt;br /&gt;
\index{Beschriftungen!TrueType}\index{Annotationen!TrueType}&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften skalieren besser als die im MapServer eingebauten Schriftarten und sehen generell besser aus, benötigen jedoch einiges an zusätzlicher Vorbereitung, beispielsweise bei der Installation und weil das Anlegen einer Font-Datei für den MapServer nötig wird. Auch der Aufwand an Rechenzeit ist merklich größer.&lt;br /&gt;
&lt;br /&gt;
Falls Sie jedoch Wert auf qualitativ hochwertige Schriften legen oder gar eine gewisse Stimmung erzeugen möchten -- indem Sie Frakturschriften in den Karten Ihrer mittelalterlichen Rollenspielwelt verwenden, um ein Beispiel zu nennen --, so kommen Sie um TrueType-Schriften nicht herum.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;strassen&amp;quot;&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  DATA &amp;quot;strassen&amp;quot;&lt;br /&gt;
  LABELITEM &amp;quot;NUMMER&amp;quot;&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;Arial&amp;quot;&lt;br /&gt;
      SIZE 12&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
      OUTLINECOLOR 255 255 255&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Typ des Labels muß natürlich =TRUETYPE=  sein. Anstelle eines von fünf festen Strings treten Angaben in Pixeln. Und natürlich muß der Name der Schrift angegeben werden -- dafür wird ein Alias verwendet, der in der Font-Datei definiert worden sein muß (siehe auch Beginn dieser Sektion).&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen im Label-Objekt lassen sich nur dann verwenden, wenn TrueType-Schriften zum Einsatz kommen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANGLE &amp;lt;double&amp;gt;=  Eine Winkelangabe in Grad, um die die Beschriftung gedreht werden soll. Kann nur in Linien-Layern benutzt werden. Wird anstatt eines Zahlenwertes =AUTO=  verwendet, richtet sich der Text an der Linie aus.  &lt;br /&gt;
*=ANTIALIAS &amp;lt;TRUE|FALSE&amp;gt;=  Schaltet Kantenglättung für Schriften an oder aus.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Name der Schriftart, wie er in der Font-Datei festgelegt worden ist.  &lt;br /&gt;
&lt;br /&gt;
==Hinweise==(16)&lt;br /&gt;
&lt;br /&gt;
Automatische Beschriftungen von ebenso automatisch generierten Karten haben einige Tücken, derer man sich bewußt sein sollte, bevor man vom Ergebnis enttäuscht wird.&lt;br /&gt;
&lt;br /&gt;
Angaben wie das zuvor genannte =BUFFER=  beispielsweise bewirken, dass diverse Labels gar nicht erst gezeichnet werden. Das kann zum Beispiel zur Folge haben, dass die kleinen Orte um  eine große Stadt durchaus beschriftet werden -- und dann aber kein Platz mehr für eine Beschriftung neben der Stadt ist und diese dann in der fertigen Karte ohne auskommen muß.&lt;br /&gt;
&lt;br /&gt;
Zu allem Überfluss können sich die Labels nach dem nächsten Zoom oder gar nur nach einem Pan so verschoben haben, dass besagte Stadt plötzlich eben doch beschriftet ist. Der Benutzer kann sich dann fragen, welch merkwürdige Karte er da vor sich hat.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, mit diesem Phänomen umzugehen. Man kann stundenlang mit Schriftgrößen und Zoomstufen herumexperimentieren -- aber der nächste Benutzer wird eben doch die Einstellung finden, an die man nicht gedacht hat.&lt;br /&gt;
&lt;br /&gt;
Sicherlich sinnvoll ist es, mit =MINSIZE=  und =MAXSIZE=  Maßstäbe festzulegen, ab denen bestimmte Beschriftungen zulässig werden. Features, die unter allen Umständen beschriftet werden sollen, sollten mit =FORCE TRUE=  dazu gezwungen werden.&lt;br /&gt;
&lt;br /&gt;
Die korrekte Vorgehensweise bei diesen Phänomen dürfte von Fall zu Fall unterschiedlich sein; auf alle Fälle sollte man sich aber der Existenz des Problems bewußt und darauf vorbereitet sein, es eventuell in Angriff nehmen zu müssen, falls jemand darauf stößt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Symbole=\index{Symbole}(17)&lt;br /&gt;
&lt;br /&gt;
Symboldateien definieren Darstellungen, die von den normalen Formen abweichen, die also mehr sind als simple Striche für Polygonumrandungen oder Linienvektoren.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Symbole entweder direkt im Mapfile als einzelne Sektionen nach dem Header. Oder aber in einer eigenen Datei, genannt =SYMBOLSET= , die im Header deklariert wird -- siehe auch Seite~\pageref{text:mapfile:header}. Begonnen wird ein Symbol mit =SYMBOL= , abgeschlossen wird es mit =END= .&lt;br /&gt;
&lt;br /&gt;
Farben werden für Symbole nicht in den Symbol-Sektionen definiert, sondern in den Classes, die die Symbole verwenden.&lt;br /&gt;
&lt;br /&gt;
MapServer kennt die folgenden Arten von Symbolen, die in Symboldateien definiert werden können, und die in einer Symbol-Sektion über =TYPE=  deklariert werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=VECTOR=  Ein oder mehrere Vektoren, die aneinandergefügt ein Symbol ergeben. Dadurch können Rechtecke, Dreiecke und andere geometrische Formen realisiert werden.   &lt;br /&gt;
*=ELLIPSE=  Ellipsen werden über zwei Radien definiert. Sind beide Werte gleich, entsteht ein Kreis. Ergänzt die geometrischen Formen, die mit =VECTOR=  möglich sind.  &lt;br /&gt;
*=PIXMAP=  Linien können mit (möglichst kleinen) Bilddateien gezogen werden. Ebenso können Polygone mit solchen Bilder ausgefüllt werden. Das Format dieser Bilder muß vom MapServer unterstützt werden. Das schließt beispielsweise ''.gif'' -Bilder aus, wenn es sich um einen MapServer handelt, der ''.png'' -Bilder generiert.  &lt;br /&gt;
*=TRUETYPE=  Einzelne Symbole aus TrueType-Schriften können zur Annotation von Features in Karten benutzt werden. Es gibt einige TrueType-Zeichensätze, die speziell für die Verwendung in Karten erstellt worden sind.  &lt;br /&gt;
&lt;br /&gt;
Ferner können sogenannte Overlaysymbole für Linien definiert werden, bei denen ein Liniensymbol über ein anderes gelegt wird; mehr dazu weiter unten.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können für Symbole gesetzt sein, wenn es sich nicht um TrueType-Symbole handelt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=NAME &amp;lt;name&amp;gt;=  Name des Symbols. Sollte immer gesetzt sein, falls man seine Symbole nicht über ihre Nummer innerhalb der Symboldatei referenzieren möchte -- was spätestens dann für Unheil sorgen wird, wenn man zusätzliche Symbole mitten in der Datei einfügt.  &lt;br /&gt;
*=FILLED &amp;lt;TRUE|FALSE&amp;gt;=  Das Symbol soll gefüllt sein.  &lt;br /&gt;
*=PIXMAP &amp;lt;dateiname&amp;gt;=  Eine Bilddatei, die als 'Pinsel' verwendet werden soll. Kommt nur für Symbole vom Typ =PIXMAP=  zur Anwendung.  &lt;br /&gt;
*=STYLE=  Eine eigene Sektion innerhalb eines Symbols, die einen Stil für Linien-Symbole definiert. Es handelt sich um einen einzelnen Punkt (referenziert als =SYMBOL 0= ), der je nach Stil an- und wieder ausgeschaltet wird. Zur Verdeutlichung ein Beispiel:  &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  STYLE    2 3 2 4  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;  Mit diesem =STYLE=  werden zwei Pixel einer Linie gezeichnet, dann drei Pixel Pause gemacht, dann werden wieder zwei Pixel gezeichnet, woraufhin wieder vier Pixel ausgelassen werden. Danach geht das ganze wieder von vorne los.  &lt;br /&gt;
*=POINTS=  Dies ist eine eigene Sektion innerhalb eines Symbols und beschreibt ein Symbol über Vektoren.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;index&amp;gt;=  Der Index der Farbe in einer Farbpalette, die bei einem Pixmap-Symbol transparent geschaltet werden soll.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Points}&lt;br /&gt;
&lt;br /&gt;
Vektor-Symbole werden über eine eigene Sektion innerhalb eines Symbols definiert, die mit =POINTS=  beginnt, mit =END=  abgeschlossen wird und Paare von Zahlen enthält; Punkte eines Vektors eben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel für ein Vektor-Symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  NAME &amp;quot;dreieck&amp;quot;&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    3 3&lt;br /&gt;
    3 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol beschreibt ein Dreieck. Beachten Sie, dass Sie für einen geschlossenen Kantenzug immer den ersten Punkt noch einmal als letzten Punkt einfügen müssen. &lt;br /&gt;
&lt;br /&gt;
Punkte, bei denen beide Koordinaten negativ sind, werden als Trenner betrachtet. Dadurch können Sie beispielsweise Kreuze und ähnliches realisieren, also Symbole, die aus mehreren Segmenten bestehen.&lt;br /&gt;
&lt;br /&gt;
==TrueType-Symbole==\index{TrueType!Symbole}\index{Symbole!TrueType}(18)&lt;br /&gt;
&lt;br /&gt;
TrueType-Schriften als Symbole funktionieren, indem man einzelne Zeichen aus der Schriftart herausgreift, und damit dann einzelne Punkte annotiert, oder das Symbol an einer Linie immer wieder wiederholt.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Unterstützung für TrueType-Schriften in den MapServer kompiliert sein muss, um diese Art von Beschriftung benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter in einer Symbol-Sektion kommen nur zum Tragen, wenn es sich um ein TrueType-Symbol handelt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=ANTIALIAS &amp;lt;FALSE|TRUE&amp;gt;=  Gibt an, ob auf dem Symbol ein Antialiasing stattfinden soll.  &lt;br /&gt;
*=CHARACTER &amp;lt;index&amp;gt;=  Die Nummer des Zeichens innerhalb der TrueType-Datei, das als Symbol benutzt werden soll.  &lt;br /&gt;
*=FONT &amp;lt;name&amp;gt;=  Alias der TrueType-Schriftart, die für das Symbol benutzt werden soll. Dieser Alias muß im =FONTSET=  definiert sein.  &lt;br /&gt;
*=GAP=  Der Abstand zwischen zwei TrueType-Symbolen. Kommt nur für Linien zur Anwendung.  &lt;br /&gt;
&lt;br /&gt;
Als Beispiel für ein TrueType-Symbol soll an dieser Stelle die Schriftart WebDings herhalten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;haus&amp;quot;&lt;br /&gt;
  TYPE TRUETYPE&lt;br /&gt;
  FONT &amp;quot;webdings&amp;quot;&lt;br /&gt;
  ANTIALIAS TRUE&lt;br /&gt;
  CHARACTER &amp;quot;&amp;amp;#71;&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel greift aus der Schriftart WingDings das Zeichen heraus, das ein kleines Häuschen darstellt. Sie könnten damit beispielsweise Ihre Ferienhäuser in der Karte markieren.&lt;br /&gt;
&lt;br /&gt;
Die Notation =\&amp;amp;\#71;=  kennen Sie vielleicht aus HTML-Seiten, wo einzelne Zeichen auf diese Weise notiert werden können. 71 ist die Position des Zeichens in der TrueType-Datei; falls Sie die Position nicht kennen, müssen Sie raten oder ein Programm zurate ziehen, dass Ihnen die einzelnen Zeichen darstellt und deren Position angibt.&lt;br /&gt;
&lt;br /&gt;
==Pixmap-Symbole==&lt;br /&gt;
&lt;br /&gt;
Pixmaps lassen sich entweder an Linien entlangziehen oder zum Füllen von Fläche verwenden. Natürlich kann man mit ihnen auch einzelne Punkte annotieren. Damit können Sie beispielsweise Ihr Firmenlogo an verschiedenen Filialen einblenden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;logo&amp;quot;&lt;br /&gt;
  TYPE PIXMAP&lt;br /&gt;
  IMAGE &amp;quot;firmenlogo.png&amp;quot;&lt;br /&gt;
  TRANSPARENT 0&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overlay-Symbole==\index{Symbole!Overlay}\index{Overlaysymbole}&lt;br /&gt;
&lt;br /&gt;
Overlaysymbole werden separat in den Klassen eines Layers definiert. Dabei werden ganz einfach die als Overlay deklarierten Symbole über die 'normalen' Symbole gelegt. Anwendung findet so etwas zum Beispiel bei Autobahnen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
CLASS&lt;br /&gt;
  ...&lt;br /&gt;
  SYMBOL 0&lt;br /&gt;
  SIZE 4&lt;br /&gt;
  COLOR 0 0 0&lt;br /&gt;
  OVERLAYSYMBOL 0&lt;br /&gt;
  OVERLAYSIZE 2&lt;br /&gt;
  OVERLAYCOLOR 255 0 0&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat ist eine vier Pixel breite schwarze Linie, auf der sich eine zwei Pixel breite rote befindet. Anders formuliert: eine zwei Pixel breite rote Linie mit einem schwarzen Rand.&lt;br /&gt;
&lt;br /&gt;
Auf diese Weise kann man beispielsweise auch gestrichelte Linien auf breite Linien legen und damit Mittelstreifen symbolisieren etc.&lt;br /&gt;
&lt;br /&gt;
Es gibt die folgenden Optionen für Overlaysymbole:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=OVERLAYSYMBOL= : Definiert wie =SYMBOL= , welches Symbol verwendet werden soll.  &lt;br /&gt;
*=OVERLAYBACKGROUNDCOLOR= : Hintergrundfarbe des Overlaysymbols  &lt;br /&gt;
*=OVERLAYCOLOR= : Farbe des Symbols  &lt;br /&gt;
*=OVERLAYMINSIZE= : Minimaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYMAXSIZE= : Maximaler Maßstab, bei dem das Overlaysymbol angezeigt werden soll.  &lt;br /&gt;
*=OVERLAYOUTLINECOLOR= : Umrandungsfarbe für das Overlaysymbol  &lt;br /&gt;
*=OVERLAYSIZE= : Größe des Overlaysymbols.  &lt;br /&gt;
&lt;br /&gt;
Diese Angaben sind also allesamt äquivalent zu den Angaben in normalen Symbolen ohne den Zusatz ''OVERLAY'' .&lt;br /&gt;
&lt;br /&gt;
Mit der Ankunft des =STYLE= -Objekts und der entsprechenden Möglichkeit, mehr als zwei Symbole übereinander zu legen, werden die Overlayparameter allerdings wohl ihre Daseinsberechtigung verlieren. Mehr dazu siehe Abschnitt~6.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
Erfahrungsgemäß bereiten Symbole gerade dem Einsteiger Schwierigkeiten. Daher sehen wir uns einige Beispiele an, die wir nach und nach zu komplexeren Symbolen ausbauen.&lt;br /&gt;
&lt;br /&gt;
Für das einfachste aller Symbole, einen Punkt, wird wohl kein Screenshot benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;punkt&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol können Sie nun in einem Layer verwenden, und dann dementsprechend die Dicke der Linie mit =SIZE=  festlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte, dass es keinen Unterschied macht, ob Sie =1 1=  oder =2 2=  in diesem Beispiel schreiben. Es handelt sich hier um Vektoren, dabei spielt der Skalar vor den eigentlichen Koordinaten keine Rolle. =2 2=  ist also das gleiche wie zweimal =1 1= , und dieses 'zweimal' wird verworfen. Wichtig ist das Verhältnis der Zahlen zueinander. Wenn Sie also eine Ellipse haben wollen, die doppelt so breit wie hoch ist, schreiben Sie =2 1= . Sie könnten auch =6 3=  schreiben, aber dadurch würde die Ellipse in der Karte nicht größer. Die Darstellungsgröße in der Karte wird über den Parameter =SIZE=  in der entsprechenden Class geregelt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste Gestaltungselement bei Linien ist die Möglichkeit, Abstände auf der Linie zu bestimmen. Damit lassen sich zum Beispiel gepunktete (''dotted'' ) oder gestrichelte (''dashed'' ) Linien realisieren. Ein Beispiel für ein Punkt-Symbol für eine Linie gestrichelte und gepunktete Linie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;funky&amp;quot;&lt;br /&gt;
  TYPE ELLIPSE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  STYLE 2 2 1 1 &lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Symbol entspricht dem letzten, mit dem Unterschied, dass hier ein =STYLE=  verwendet wird. Die Angabe bedeutet, dass die ersten zwei Pixel des Linienzuges gezeichnet werden sollen, die nächsten beiden dann wieder nicht; danach wird ein Pixel gesetzt, der folgende dann wieder nicht. Es wird also immer die bezeichnete Anzahl von Pixeln gesetzt und dann wieder nicht gesetzt. Danach fängt das ganze wieder von vorne an. Beachten Sie bitte, dass die hier benutzte =STYLE= -Eigenschaft nichts mit dem Style-Objekt zu tun hat, wie es weiter vorne beschrieben worden ist.&lt;br /&gt;
&lt;br /&gt;
Auf Beispiele für Overlaysymbole soll hier nicht eingegangen werden, da diese Methode veraltet ist. Stattdessen sollten Style-Objekte in den Classes benutzt werden.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.65}{symbols-star}{Städte, markiert mit einem sternförmigen Vektorsymbol.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Falls Sie mal ein komplexeres Symbol sehen wollen, schauen Sie sich die Sternchen in Abbildung~\ref{symbols-star} an. Die Sterne kommen folgendermaßen zustande:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
SYMBOL&lt;br /&gt;
  NAME &amp;quot;stern&amp;quot;&lt;br /&gt;
  TYPE VECTOR&lt;br /&gt;
  FILLED TRUE&lt;br /&gt;
  POINTS&lt;br /&gt;
    0 .375&lt;br /&gt;
    .35 .375&lt;br /&gt;
    .5 0&lt;br /&gt;
    .65 .375&lt;br /&gt;
    1 .375&lt;br /&gt;
    .75 .625&lt;br /&gt;
    .875 1&lt;br /&gt;
    .5 .75&lt;br /&gt;
    .125 1&lt;br /&gt;
    .25 .625&lt;br /&gt;
  END&lt;br /&gt;
END &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich also um ein Vektorsymbol, das aus zehn Punkten besteht. Sie können sich beim Entwurf eigener Symbole das ganze auf Karo- oder Millimeterpapier aufmalen und dann die Koordinaten ablesen. Der Ursprung für Ihr Koordinatensystem muß in der linken oberen Ecke liegen. Beachten Sie, dass der höchste Wert in den Koordinaten der Punkte =1=  ist. Sie könnten die auch alle Werte beispielsweise mit zwei multiplizieren, und es würde keinen Unterschied machen. Das ist der Effekt der Vektorrechnung, der weiter oben erläutert ist.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Markierungen für Gefälle}&lt;br /&gt;
&lt;br /&gt;
Insbesondere während Schulungen wird der Autor gerne gefragt, wie es sich mit der Gestaltung von Höhenlinien verhielte; dabei möchte man beispielsweise in der abfallenden Richtung einer Höhenlinie in regelmäßigen Abständen einen kleinen, parallel zur Linie verlaufenden Strich anbringen, um die Richtung des Gefälles anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Dazu muß leider gesagt werden, dass diese Art der Gestaltung insbesondere bei Shapefiles ''nicht''  möglich ist, da Shapefiles keine Topologie oder eine Richtungsinformation speichern. Zwar werden Sie GIS-Programme sehen, bei denen sich eine solche Gestaltung vornehmen läßt. Allerdings speichert die betreffende Software dann eine entsprechende Information über die Laufrichtung der Shapes separat ab. Diese Möglichkeit ist MapServer wegen seiner rein darstellerischen Fähigkeiten verschlossen.&lt;br /&gt;
&lt;br /&gt;
=Maßstäbe=(19)&lt;br /&gt;
\index{Maßstab}\index{Scalebar}\index{Mapfile!Maßstab}\index{Mapfile!Scalebar}&lt;br /&gt;
&lt;br /&gt;
Maßstäbe setzen die Größen auf der Karte in eine Relation zur Realität. Dieser Zusammenhang wird einem am Computerbildschirm jedoch zum Verhängnis.&lt;br /&gt;
&lt;br /&gt;
Man sollte nicht auf die Idee kommen, einen Pixelmaßstab auf dem Bildschirm auszumessen, und etwa zu sagen: &amp;quot;`Ah, 10 Pixel sind 100 Meter, und 10 Pixel sind 0.5 Zentimeter, also sind 0.5 Zentimeter 100 Meter.&amp;quot;' Ein Maßstab auf dem Bildschirm steht ausschließlich in Relation zur angezeigten Karte, nicht zur realen Welt, da sich Pixel nicht in Zentimeter umrechnen lassen, sondern stets von der Größe des Bildschirms und der verwendeten Auflösung abhängig sind.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Maßstab für 10 Pixel in der Karte 100 Meter in der Realität angibt, dann sind diese zehn Pixel bei 1280x1024 Pixeln Auflösung auf einem 19 Zoll Bildschirm wesentlich kleiner als bei einer Auflösung von 800x600 Pixeln auf einem 14 Zoll Bildschirm.&lt;br /&gt;
&lt;br /&gt;
MapServer geht bei Maßstabsangaben (=SCALE= ) immer von &amp;lt;math&amp;gt;\frac{1}{72}&amp;lt;/math&amp;gt; inch pro Pixel aus. Dieser Wert kann allerdings bestenfalls als vage Annäherung betrachtet werden. Bei =SCALE=  handelt es sich immer um den Kehrwert eines Maßstabes. Wenn Sie den Maßstab also beispielsweise als 1:20000 kennen, ist =SCALE=  gleich 20000.&lt;br /&gt;
&lt;br /&gt;
Bei den Beschriftungen für Maßstäbe im MapServer beachten Sie bitte, dass MapServer bisher noch keinen Gebrauch von TrueType-Schriften an dieser Stelle macht.&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Maßstäbe im Mapfile wird mit =SCALEBAR=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion stehen und muss nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=BACKGROUNDCOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für den Scalebar, ''nicht''  für das komplette Bild, das den Scalebar ausmacht.  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund des Scalebars ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Hintergrundfarbe für das Bild, in dem sich der Scalebar befindet.  &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Die Farbe, in der der Scalebar gemalt werden soll.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  legt fest, ob der fertige Maßstab interlaced sein soll.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite des Scalebars in Pixeln. Das ist nicht die Größe des fertigen Bildes, sondern nur des Maßstabs im Bild. Auch Beschriftungen werden hier noch nicht einberechnet.  &lt;br /&gt;
*=INTERVALS=  Anzahl der Intervalle auf dem Maßstab. Voreinstellung ist 4.  &lt;br /&gt;
*=UNITS &amp;lt;feet|inches|kilometers|meters|miles&amp;gt;=  Die Einheit, in der der Maßstab beschriftet sein soll. Voreinstellung ist Meilen. Gradangaben sind übrigens keine sinnvollen Einheiten für einen Maßstab. Voreinstellung ist =miles= .  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die einzelnen Intervalle des Maßstabs. Soll keine Umrißfarbe verwendet werden, reicht als Wert auch =-1= .  &lt;br /&gt;
*=STYLE &amp;lt;0|1&amp;gt;=  Es gibt zwei verschiedene Styles. Style =1=  ist im wesentlichen ein horizontaler, beschrifteter Strich, während Stil =0=  in weiße und schwarze Sektionen unterteilt ist.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet den Maßstab an oder aus. Mit =EMBED=  wird der Maßstab angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einem in die Karte eingebetteten Maßstab wird dieser an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Maßstäbe verwendet, die in die Karte eingebettet sind. Der Maßstab wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=Legenden=&lt;br /&gt;
\index{Legende}\index{Mapfile!Legende}&lt;br /&gt;
&lt;br /&gt;
Legenden erklären die in der Karte verwendeten Symbole und Zeichen. Ohne eine Legende ist eine Karte prinzipiell ohne Inhalt, da man ohne sie den Linien, Farben usw. keine Bedeutung zuordnen kann.&lt;br /&gt;
&lt;br /&gt;
MapServer ist in der Lage, konfigurierbare Legenden automatisch zu generieren. Diese Legenden können dann auf die bekannte Weise über Template-Tags in das Layout der Applikation eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
Neben den klassischen Bitmap-Legenden (die gesamte Legende ist ein einziges Bild, das in eine HTML-Seite eingebunden wird), gibt es seit der Version~{3.6} auch HTML-Legenden, die über Templates kleine HTML-Abschnitte erzeugen.&lt;br /&gt;
&lt;br /&gt;
==Die klassische MapServer-Legende==&lt;br /&gt;
&lt;br /&gt;
Diese Art von Legende ist ein fertiges Bild, das vom MapServer generiert wird. Auf die Gestaltung dieser Legende hat man nicht so viel Einfluss wie bei der HTML-Legende (siehe weiter unten).&lt;br /&gt;
&lt;br /&gt;
Die Sektion für Legenden im Mapfile wird mit =LEGEND=  eingeleitet. Sie darf nicht innerhalb einer anderen Sektion vorkommen und muß nach dem Header stehen. Die folgenden Parameter sind für diese Sektion bekannt:&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.35}{legende}{Die drei Vektorlayertypen in einer klassischen MapServer-Legende: Punkte, Linien und Polygone}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=IMAGECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Hintergrundfarbe für die fertige Legende  &lt;br /&gt;
*=TRANSPARENT &amp;lt;ON|OFF&amp;gt;=  Schaltet Transparenz für den Hintergrund der Legende ein oder aus. Voreingestellt ist der Hintergrund nicht transparent.  &lt;br /&gt;
*=OUTLINECOLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Umrissfarbe für die Kästchen, die die Symbole in der Legende umranden.  &lt;br /&gt;
*=KEYSIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Breite und Höhe der Symbole in der Legende in Pixeln. Vorgabe ist 20x10.  &lt;br /&gt;
*=KEYSPACING &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Horizontaler und vertikaler Abstand der Symbole bzw. der Beschriftungen zueinander. Vorgabe ist 5 und 5.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF|EMBED&amp;gt;=  Schaltet die Legende an oder aus. Mit =EMBED=  wird die Legende angeschaltet und in die fertige Karte eingebettet.  &lt;br /&gt;
*=POSITION &amp;lt;ul|uc|ur|ll|lc|lr&amp;gt;=  Bei einer in die Karte eingebetteten Legende wird diese an der angegebenen Position dargestellt. In der Tabelle in der PHP MapScript-Referenz, die auf Seite~\pageref{tab:ref:mapscript:const} beginnt, finden Sie eine Erklärung der möglichen Werte.  &lt;br /&gt;
*=INTERLACE &amp;lt;TRUE|FALSE&amp;gt;=  Ob das Bild interlaced sein soll.  &lt;br /&gt;
*=POSTLABELCACHE &amp;lt;TRUE|FALSE&amp;gt;=  Wird nur für Legenden verwendet, die in die Karte eingebettet sind. Die Legende wird dann erst in die Karte eingefügt, nachdem alle Labels in der Karte gezeichnet worden sind. Voreinstellung ist =FALSE= .  &lt;br /&gt;
*=LABEL=  An dieser Stelle wird ein separates =LABEL= -Objekt eingefügt, das für die Beschriftung des Maßstabs zuständig ist. Bisher können in Maßstäben keine TrueType-Schriften verwendet werden.  &lt;br /&gt;
*=TEMPLATE=  Definiert ein Template, das für HTML-Legenden verwendet werden soll. Siehe den folgenden Abschnitt über HTML-Legenden.  &lt;br /&gt;
&lt;br /&gt;
In Abbildung \ref{legende} kann man sehen, wie Legenden für verschiedene Arten von Vektorlayern aussehen. Polygone werden durch ein Rechteck dargestellt, das gegebenenfalls eine Füllfarbe hat. MapServer bedient sich an dieser Stelle bei den Angaben im Mapfile. Punktlayer werden durch einen (wenig überraschend) Punkt dargestellt, während Linienlayer eine kleine gezackte Linie bekommen.&lt;br /&gt;
&lt;br /&gt;
==HTML-Legenden==\index{HTML-Legenden}&lt;br /&gt;
&lt;br /&gt;
Als Alternative zu den normalen .gif- beziehungsweise .png-Bildern, die als Legenden generiert werden, gibt es für die CGI-Version des MapServers noch die Möglichkeit, eigene Legenden über HTML-Templates zu gestalten. Die fertige Legende wird dabei weiterhin an der Stelle im Haupt-Template eingefügt, an der das Schlüsselwort =[legend]=  steht.&lt;br /&gt;
&lt;br /&gt;
Interessant wird eine HTML-Legende dann, wenn man in die kleinen Bruchstücke von HTML auch Teile des Formulars zur Navigation in der Karte einfügt -- später mehr dazu.&lt;br /&gt;
&lt;br /&gt;
Im LEGEND-Block des Mapfiles kann ein TEMPLATE definiert, etwa folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LEGEND&lt;br /&gt;
  ...&lt;br /&gt;
  TEMPLATE &amp;quot;legend.html&amp;quot;&lt;br /&gt;
END  &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Aufbau des Templates}&lt;br /&gt;
&lt;br /&gt;
Innerhalb eines Templates können drei verschiedene Blöcke definiert werden: für Groups, Layers und Classes. Diese Begriffe folgen den Bedeutungen im Mapfile. Es kann also HTML-Code für Gruppen von Layern generiert werden, für die Layer in diesen Gruppen und dann für jede einzelne Class in diesen Layern wiederum eigener Code. Dieser Aufbau eignet sich besonders für den Aufbau in HTML-Tabellen.&lt;br /&gt;
&lt;br /&gt;
Alle Inhalte der Templatedatei, die sich außerhalb der möglichen Blöcke befinden werden schlicht ignoriert und eignen sich somit dafür, Kommentare einzufügen, die später in der fertigen HTML-Seite nicht erscheinen sollen. Für Kommentare innerhalb der Blöcke müssen selbstverständlich HTML-konforme Kommentare benutzt werden, die mit =&amp;lt;!--=  eingeleitet und =--&amp;gt;=  abgeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Für gewöhnlich werden mit Groups- und Layerblöcken Kopfzeilen für HTML-Bereiche definiert, in denen dann die einzelnen Classes der Reihe nach aufgelistet werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Mit der Verwendung eines solchen Blocks legt man die Erzeugung von Legenden fest, in denen Layer gruppiert dargestellt werden, und zwar anhand ihrer Gruppierung im Mapfile. Wird eine Groups-Sektion verwendet, werden alle Gruppierungen als solche in der Legende dargestellt. Möchte man keine Gruppierung von Layern in der Legende, verwendet man diesen Block einfach nicht.&lt;br /&gt;
&lt;br /&gt;
Wird dieser Block definiert, erscheinen Layer nicht in der Legende, die zu keiner Gruppe gehören, und ebensowenig sind deren Classes zu sehen.&lt;br /&gt;
&lt;br /&gt;
Mit =[leg_group_html]=  wird ein solcher Block eingeleitet, und mit einem entsprechenden =[/leg_group_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags können in einem Group-Block erscheinen:&lt;br /&gt;
     &lt;br /&gt;
*=[leg_group_name]= : Gibt den Namen der Gruppe aus.    &lt;br /&gt;
*=[leg_icon &amp;lt;width=X&amp;gt; &amp;lt;height=Y&amp;gt;]= : Steht für das erzeugte Icon. Der erzeugte Text ist der URL zu diesem Icon. Im Kontext einer Group gibt dieser Tag das Icon für den ersten Layer in der Group zurück.    Die beiden Parameter =width=  und =height=  sind optional und verändern die Breite und die Höhe des fertigen Icons.    &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]= : Ist der MapServer über entsprechende Einträge im Mapfile OGC-konform ausgelegt, können an dieser Stelle entsprechende Metadaten ausgegeben werden. Mehr zu OGC-konformen Mapservern gibt es in Kapitel~\ref{text:ogc} zu erfahren. Auch andere Metadaten aus der Web-Sektion, wie Sie in Abschnitt~21 beschrieben sind, lassen sich hier einfügen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Analog zu Groups wird mit =[leg_layer_html]=  ein Block für einen Layer in der HTML-Legende eingeleitet und mit =[/leg_layer_html]=  wieder abgeschlossen. Im startenden Tag können allerdings noch einige zusätzliche Parameter übergeben werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=order_metadata=&amp;lt;schlüssel&amp;gt;=  In Abschnitt~21 haben Sie erfahren, dass Sie in Layern beliebige Metadaten in einem eigenen Block speichern können. Anhand solcher Einträge können Sie nun die Reihenfolge der Layer in der HTML-Legende kontrollieren. Anschaulich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  LAYER    ...    METADATA      legendenposition 2    END    ...  END  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Haben Sie ein jedem Layer eine solche Klassifizierung, können Sie in der HTML-Legende die Sortierung kontrollieren mit:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  [leg_layer_html order_metadata=legendenposition]  ...  [\leg_layer_html]  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=opt_flag=&amp;lt;wert&amp;gt;=  Dieser Wert kontrolliert die Verhaltensweise dieses Layerblocks. Es handelt sich um eine Bitmaske, d.h. für eine Kombination der folgenden Optionen addieren Sie die entsprechenden Werte aufeinander auf. Sie werden immer eine eindeutige Zahl erhalten. Die Werte sind:       &lt;br /&gt;
*&lt;br /&gt;
*=1=  Zeigt den Layer in der Legende an, auch wenn sich der gezeigte Ausschnitt außerhalb des Layers befindet. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=2=  Zeigt den Layer in der Legende an, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=4=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =QUERY=  gesetzt ist und daher nur befragt werden kann, aber nicht in der Karte erscheint. Dieses Verhalten ist nicht voreingestellt.  &lt;br /&gt;
*&lt;br /&gt;
*=8=  Zeigt den Layer in der Legende an, auch wenn sein =TYPE=  auf =ANNOTATION=  gesetzt ist und daher nur Beschriftungen darstellt. Dieses Verhalten ist nicht voreingestellt.      Möchten Sie beispielsweise die ersten beiden Optionen zulassen, setzen Sie =opt_flag=  auf &amp;lt;math&amp;gt;1+2=3&amp;lt;/math&amp;gt;.    Selbstverständlich können in einem Layer-Block in der Legende eigene Tags verwendet werden:       &lt;br /&gt;
*&lt;br /&gt;
*=[leg_layer_name]=  Fügt den Namen des Layers an dieser Stelle ein.  &lt;br /&gt;
*&lt;br /&gt;
*=[leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;]=  Fügt den URL eines automatisch generierten Legenden-Icons ein, wie man es auch aus der klassischen MapServer-Legende kennt. Die Breiten- und Höhenangaben erfolgen in Pixeln und sind optional. Wenn ein Layer mehrere Classes aufweist, wird ein Icon für die erste Class im Layer generiert.  &lt;br /&gt;
*&lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion des Layers ein -- siehe auch weiter oben.      &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Und natürlich kommen auch die Classes in HTML-Legenden zu ihrem Recht. Sie werden mit =[leg_class_html]=  eingeleitet und am Ende mit =[/leg_class_html]=  wieder abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Ebenso wie die Blöcke für Layer kennen auch die Blöcke für Classes den Parameter =opt_flag= . Wenn er verwendet wird, wird er auch mit den gleichen Parametern gefüttert wie sein Pendant im Layer-Block.&lt;br /&gt;
&lt;br /&gt;
Bitten beachten Sie, das Classes ohne einen =NAME=  nicht in HTML-Legenden auftauchen werden.&lt;br /&gt;
&lt;br /&gt;
Sie können die folgenden Tags innerhalb eines Class-Blockes in HTML-Legenden verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[leg_class_name]=  Der Name der Klasse. Jede Klasse, die überhaupt in der Legende auftauchen soll, benötigt einen Namen.  &lt;br /&gt;
*=leg_icon width=&amp;lt;breite&amp;gt; height=&amp;lt;höhe&amp;gt;=  Das Legenden-Icon für die Class, wie im Layer beschrieben.  &lt;br /&gt;
*=[metadata name=&amp;lt;feld&amp;gt;]=  Fügt beliebige Metadaten aus der entsprechenden Sektion der Class ein; siehe auch weiter oben.  &lt;br /&gt;
&lt;br /&gt;
\subsection*{Konditionale in HTML-Legenden}\index{HTML-Legenden!Konditionale}&lt;br /&gt;
&lt;br /&gt;
Konditionale sind Wenn-Dann-Anweisungen. Aus einer Programmiersprache wie C kennt man das unter der folgenden Notation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
if (&amp;lt;bedingung&amp;gt; {&lt;br /&gt;
  ... hier passiert etwas ...&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
  ... hier passiert etwas anderes ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solche Konditionale lassen sich auch in HTML-Legenden nutzen, etwa um Dinge nur unter bestimmten Bedingungen einzublenden. Es gibt eine gemeinsame Notation, aber für jeden möglichen Block (Group, Layer und Class) eigene Eigenschaften, die abgefragt werden können.&lt;br /&gt;
&lt;br /&gt;
Um es ein wenig genauer zu nehmen: es handelt sich weniger um eine Wenn-Dann-Anweisung, als vielmehr um ein reines Wenn. Ein ''else''  ist nicht implementiert.&lt;br /&gt;
&lt;br /&gt;
Notiert werden Konditionale folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[if name=&amp;lt;feld&amp;gt; oper=&amp;lt;operator&amp;gt; value=&amp;lt;wert&amp;gt;] ... [/if]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heißt soviel wie: Vergleiche =feld=  dahingehend, ob es in der Beziehung =oper=  zum Wert =wert=  steht. Wenn das der Fall ist, füge den Block bis zum =[/if]=  ein.&lt;br /&gt;
&lt;br /&gt;
Da das reichlich abstrakt ist, hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html]&lt;br /&gt;
  [if name=layer_type oper=eq value=2]&lt;br /&gt;
    &amp;lt;p&amp;gt;[leg_layer_name]&amp;lt;/p&amp;gt;&lt;br /&gt;
  [/if]&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Layer-Block wird der Name des Layers immer dann ausgegeben, wenn sein Typ gleich 2 ist. Der Typ 2 ist nur im Kontext von Layern definiert: Sie erfahren weiter unten, welche Werte wofür stehen.&lt;br /&gt;
&lt;br /&gt;
Das =eq=  steht für ''equal''  und bedeutet 'gleich'. Daneben gibt es noch =neq=  (ist nicht gleich), =isset=  (hat überhaupt einen Wert) und =isnull=  (ist leer). Die Voreinstellung ist =eq= . Wenn man diesen Operator verwenden möchte, kann man den Teil mit =oper==  auch weglassen.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Groups}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Group-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=group_status=  Der Status einer Group ist gleich dem =STATUS=  des ersten Layers in der selben. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag in der Web-Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layers}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Konditionale können als =name=  in Layer-Blöcken in HTML-Legenden benutzt werden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=layer_name=  Der Name des Layers.  &lt;br /&gt;
*=layer_group=  Der Name der Group, in dem sich der Layer befindet.  &lt;br /&gt;
*=layer_status=  Der Status des Layers. Als Werte kommen in Frage: =0=  für =OFF= , =1=  für =ON=  und =2=  für =DEFAULT= .  &lt;br /&gt;
*=layer_type=  Der Typ des Layers. Infrage kommen: =0=  für =POINT= . =1=  für =LINE= , =2=  für =POLYGON= , =3=  für =RASTER= . =4=  für =ANNOTATION=  und =5=  für =QUERY= .  &lt;br /&gt;
*=&amp;lt;metadata&amp;gt;=  Jeder Metadaten-Eintrag aus der Layer- wie aus der Web.Sektion läßt sich als Wert für ein Konditional benutzen.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Classes}&lt;br /&gt;
&lt;br /&gt;
Schließlich bleiben noch die Konditionale, die als =name=  in Class-Blöcken in HTML-Legenden benutzt werden können. Um genau zu sein, sind die Werte hier vollständig mit denen im Layer-Block identisch, sodass sich eine Aufzählung erübrigt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Hinweise}&lt;br /&gt;
&lt;br /&gt;
Für HTML-Legenden benötigen Sie mindestens die Version 3.5.1 des Mapervers.&lt;br /&gt;
&lt;br /&gt;
Der 'traditionelle' =[legend]= -Block liefert den URL eines Bildes zurück, wohingegen HTML-Legenden (wenig überraschend) Blöcke von HTML zurückliefern.&lt;br /&gt;
&lt;br /&gt;
Wenn der HTML-Legendenmodus über die aufrufende URL für den MapServer angegeben wird, aber kein Template im Mapfile für die Legende definiert ist, wird weiterhin ein Bild erzeugt.&lt;br /&gt;
&lt;br /&gt;
\subsection*{Beispiel}&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel soll erhellen, wie man die Macht von HTML-Legenden ausschöpfen kann. Betrachten Sie die folgenden Zeilen, die ein Ausschnitt aus einem Legenden-Template sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
[leg_layer_html opt_flag=3]&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot;&lt;br /&gt;
	       value=&amp;quot;[leg_layer_name]&amp;quot; [[leg_layer_name]_check]&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;[leg_icon width=18 height=12]&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[leg_layer_name]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
[/leg_layer_html]&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist in Abbildung~\ref{mapfile-legende-html} zu sehen.&lt;br /&gt;
&lt;br /&gt;
Der Block definiert, wie Legenden für die im Mapfile vorhandenen Layer in der Legende auftauchen sollen. Der Wert 3 für =opt_flag=  sagt, dass ein Layer in der Legende stehen soll, auch wenn sich alle Daten des Layers außerhalb des dargestellten Ausschnitts befinden, und dass er in der Legende stehen soll, auch wenn sein =STATUS=  auf =OFF=  gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.3}{mapfile-legende-html}{HTML-Legenden im Einsatz}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Es folgt eine Zeile in einer HTML-Tabelle, die aus drei Spalten besteht. In der letzten Spalte steht der Name des Layers. In der vorletzten Spalte wird die Quelle für das Bild vom MapServer eingefügt, hier mit einer Größe von 18 mal 12 Pixeln.&lt;br /&gt;
&lt;br /&gt;
Die erste Zeile ist etwas trickreicher. Hier wird eine Checkbox für ein HTML-Formular generiert, die als ''value''  den Namen des Layers erhält. Dadurch wird dem MapServer mitgeteilt, welche Layer darzustellen sind und welche nicht -- der Benutzer klickt einfach die Checkboxen an.&lt;br /&gt;
&lt;br /&gt;
Der letzte Teil ist der interessante: wenn ein Layer beim letzten Aufruf angezeigt worden ist, sucht MapServer in Templates nach Tags wie =layername_check=  und ersetzt diese Tags dann durch =checked= . Dadurch wird die Checkbox im Browser markiert. Die Namen der Layer werden hier jedoch nicht hartkodiert, sondern bei der Abarbeitung des Legenden-Templates der Reihe nach ersetzt. Dadurch entsteht für jeden Layer eine passende Checkbox.&lt;br /&gt;
&lt;br /&gt;
Dieses Stück HTML-Code generiert also nicht nur eine Legende, sondern auch gleich die Elemente für das Navigationsformular aus dem Inhalt des Mapfiles. Wird dem Mapfile nun ein neuer Layer hinzugefügt (oder ein Layer entfernt), wird die Legende automatisch korrekt generiert, ohne dass man am Template etwas ändern müßte.&lt;br /&gt;
&lt;br /&gt;
=Templates=&lt;br /&gt;
(20)&lt;br /&gt;
\index{Templates}\index{Mapfile!Templates}&lt;br /&gt;
&lt;br /&gt;
In der Web-Sektion des Mapfiles können diverse Templates definiert werden, die als Ergebnis eines Aufrufs ausgeliefert werden können. Bei den Templates handelt es sich um HTML-Dateien, in denen neue, MapServer-eigene Tags definiert werden, die in eckigen Klammern notiert werden.&lt;br /&gt;
&lt;br /&gt;
Damit ein Template als Ergebnis ausgeliefert wird, muß der Modus =browse=  im URL angegeben sein, im Gegensatz zum Modus =map= , der lediglich die Karten als Bilder zurückliefert.&lt;br /&gt;
&lt;br /&gt;
Auch für die beiden Abfragemodi =query=  und =nquery=  werden Templates verwendet. Was es mit Queries auf sich hat, und wie man sie in seine Applikationen einbaut, ist ab Seite~\pageref{text:mapfile:queries} in Erfahrung zu bringen.&lt;br /&gt;
&lt;br /&gt;
==Die verschiedenen Arten von Templates==&lt;br /&gt;
&lt;br /&gt;
Templates kommen an mehreren verschiedenen Stellen im Mapfile mit unterschiedlicher Notation vor. Hier eine Aufzählung aller Möglichkeiten, ein Template für diverse Anwendungsfälle zu deklarieren.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich können Templates lokal im Dateisystem liegen, wobei dann ihr Dateiname angegeben wird. Templates können aber auch als URL deklariert werden und somit von entfernten Rechnern herbeigeholt werden.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Web-Sektion}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion kennt die folgenden Template-Angaben:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Ist das Template für die Applikation, die im Modus =browse=  läuft. Das einzige Template, das beim simplen Navigieren in der Karte zum Einsatz kommt.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Ein Kopf-Template, das ausgegeben wird, bevor irgendwelche MapServer-Ergebnisse generiert werden. Findet lediglich beim Modus =nquery=  zusammen mit =FOOTER=  Anwendung, um die verschiedenen Abfrageergebnisse in ein beginnendes und ein abschließendes HTML einbetten zu können.  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =HEADER= , das nach dem Einfügen aller Ergebnisse angehängt wird.  &lt;br /&gt;
*=MINTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der minimale =SCALE=  für die Anwendung (gesetzt durch =MINSCALE=  in der Web-Sektion) unterschritten wird. Auf diese Weise kann man MapServer-App\-li\-ka\-tionen verschiedener Detailstufen ineinander verschachteln.  &lt;br /&gt;
*=MAXTEMPLATE &amp;lt;datei|url&amp;gt;=  Ein Template, das benutzt werden soll, wenn der maximale =SCALE=  für die Anwendung (gesetzt durch =MAXSCALE=  in der Web-Sektion) überschritten wird.  &lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Layer-Sektion}&lt;br /&gt;
&lt;br /&gt;
In der Layer-Sektion lassen sich die folgenden Template-Angaben machen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht (siehe weiter unten).  &lt;br /&gt;
*=FOOTER &amp;lt;datei|url&amp;gt;=  Kommt bei multiplen Abfragen zum Tragen und wird angehängt, nachdem alle Ergebnisse zusammengefügt worden sind.  &lt;br /&gt;
*=HEADER &amp;lt;datei|url&amp;gt;=  Das Pendant zu =FOOTER= ; wird vor allen Abfrageergebnissen eingefügt.  &lt;br /&gt;
&lt;br /&gt;
Das Template via =TEMPLATE=  benutzt man im wesentlichen dann, wenn man nicht, wie im folgenden beschrieben, ein solches Template in jeder Class des Layers haben möchte.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Class-Sektion}&lt;br /&gt;
&lt;br /&gt;
Für eine Class gibt es nur eine Template-Angabe, namentlich die folgende:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=TEMPLATE &amp;lt;datei|url&amp;gt;=  Präsentiert Abfrageergebnisse. Wenn mehrere Abfrageergebnisse präsentiert werden sollen, wird für jedes der Ergebnisse dieses Template einmal eingefügt und Gebrauch von =HEADER=  und =FOOTER=  gemacht, in dem sich die Class befindet.  &lt;br /&gt;
&lt;br /&gt;
Wenn man nicht für jede einzelne Class ein =TEMPLATE=  notieren möchte, kann man eine solche Angabe auch auf der Ebene des Layers machen.&lt;br /&gt;
&lt;br /&gt;
==Aufbau==&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Beispiel für ein HTML-Template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Beispiel&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;img src=&amp;quot;[img]&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der MapServer über den URL aufgerufen wird, findet er in der Web-Sektion die Angabe für das Template, ersetzt die Tags in eckigen Klammern durch seine neu generierten Werte, und liefert dann die fertige HTML-Seite aus.&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel würde der MapServer eine Karte generieren, die einen URL zugewiesen bekommt. Dieser URL würde anstelle des =[img]= -Tags eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Für die Templates, die für die Ergebnisse von multiplen Abfragen generiert werden, gilt, dass es sich nicht um komplette HTML-Dateien handeln darf. Beispielsweise möchten Sie für ein Abfrageergebnis einer Class eventuell folgendes Template definieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[ID]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[NAME]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[AREA]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Tabelle und alles andere, was für eine vollständige HTML-Datei vonnöten ist, erfolgt dann durch weitere Templates in =HEADER=  und =FOOTER= .&lt;br /&gt;
&lt;br /&gt;
Für Templates, die das Navigationsinterface beschreiben (=TEMPLATE=  in der Web-Sektion) und solche für die Präsentation von einzelnen Abfrageergebnissen (definiert durch =TEMPLATE=  in Layern) sind hingegen natürlich vollständige HTML-Dateien notwendig.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden nun alle möglichen Tags, die vom MapServer unterstützt werden. Sie können übrigens auch eigene Tags definieren. Wenn Sie einen Parameter im URL übergeben, der dem MapServer nicht bekannt ist, wird dieser im Template ersetzt, wenn ein entsprechender Tag vorhanden ist. Wenn im URL also =meintag=17=  steht, und im Template ein Tag =[meintag]=  zu finden ist, wird dieser durch 17 ersetzt. Es gibt auch immer eine Fassung, bei der Sonderzeichen (Leerzeichen etc.) durch Escapesequenzen markiert sind; für diese Tags muß dann ein =_esc=  angehängt werden. Für das genannte Beispiel hieße der Tag also =[meintag_esc]= .&lt;br /&gt;
&lt;br /&gt;
Zuvorderst einige allgemeine Tags:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[version]= : Die Versionsnummer des eingesetzten MapServers.    &lt;br /&gt;
*=[id]= : Eine (recht)\footnote{Die Einschränkung 'recht' eindeutig soll hier nur bedeuten, dass keine Eindeutigkeit im mathematischen Sinne vorliegt. Einem Kryptographen würden sich die Haare sträuben bei der Verwendung der Session-ID als Baustein für einen 'eindeutigen' Wert. Zur Vermeidung von Kollisionen bei unseren dynamisch generierten Bildern sollte sie jedoch ausreichen.} eindeutige Session-ID für den Aufruf des MapServers, zusammengesetzt aus momentanem Datum und Zeit, sowie der Prozess-ID des Aufrufs. Diese ID ist also solange eindeutig, wie man pro Sekunde nicht mehr Anfragen bekommt, als das System gleichzeitig Prozesse starten kann.     Man hätte dann allerdings noch ganz andere Probleme, als dass die ID des MapServer-Aufrufes nicht mehr eindeutig sein könnte.    &lt;br /&gt;
*=[host]= : Der Hostname des ausführenden Rechners.    &lt;br /&gt;
*=[port]= : Der Port, auf dem der Webserver die Anfrage entgegengenommen hat. In den meisten Fällen ist dies 80.    &lt;br /&gt;
*=[web_meta data &amp;lt;key&amp;gt;]= : Zeigt die Metadaten aus der Web-Sektion eines OGC-konformen Mapfiles an.  &lt;br /&gt;
&lt;br /&gt;
Tags für Verweise auf Dateien:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[img]= : Der URL, an dem sich das neu generierte Kartenbild befindet.    &lt;br /&gt;
*=[ref]= : Dito für eine eventuell erzeugte Referenzkarte.    &lt;br /&gt;
*=[legend]= : Dito für eine eventuell erzeugte Legende.    &lt;br /&gt;
*=[scalebar]= : Dito für eine eventuell erzeugte Maßstabsleiste.    &lt;br /&gt;
*=[queryfile]= : Pfad zu dem File, in dem eine Query abgespeichert worden ist, falls =savequery=  als Parameter gesetzt wurde. Mehr zu diesem Thema im Abschnitt über Queries, siehe Seite~\pageref{text:mapfile:query:cached}.    &lt;br /&gt;
*=[map]= : Pfad zum Mapfile.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags lassen sich für Angaben über die Bildgeometrie verwenden:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[center]= : Gibt das Zentrum des Bildes in Pixeln an.    Beispiel: ist das fertige Bild 300x300 Pixel groß, so steht in diesem Tag 149,149.    Wofür braucht man das? Wenn man in einem Navigationsformular einen Knopf zum 'Auffrischen' der Karte hat (man möchte beispielsweise Layer hinzuschalten, aber den Ausschnitt nicht ändern), so kommt kein Klick in der Karte zustande, der den MapServer auf das neue Zentrum für den anzuzeigenden Ausschnitt hinweist. Mit diesem Tag ist jedoch im Formular folgendes Konstrukt möglich:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;imgext&amp;quot; value=&amp;quot;[center]&amp;quot;&amp;gt;  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Dadurch wird ein impliziter Mausklick auf das Zentrum der Karte gesetzt.    &lt;br /&gt;
*=[center_x]=  und =[center_y]= : Die x- und y-Koordinate des Bildzentrums als einzelne Werte.  &lt;br /&gt;
*=[mapsize]= : Die momentane Größe der Karte in Breite und Höhe in Pixeln, getrennt durch ein Leerzeichen. Mit einem =_esc=  am Ende auch als escaped Version vorhanden.  &lt;br /&gt;
*=[mapwidth]=  und =[mapheight]= : Breite beziehungsweise Höhe der Karte in Pixeln.  &lt;br /&gt;
*=[scale]= : Maßstab der Karte. Zu Maßstäben siehe vor allen Dingen auch Abschnitt~19  &lt;br /&gt;
&lt;br /&gt;
Angaben über die Geometrie der Karte sind mit folgenden Tags möglich. Die letzten drei Punkte in dieser Aufzählung sind nur dann verfügbar, wenn der MapServer mit der Projektionsbibliothek proj.4 kompiliert worden ist und es eine Projektionsangabe im Mapfile gibt.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[mapx]=  und =[mapy]= : x- und y-Koordinate des Mausklicks.  &lt;br /&gt;
*=[mapext]=  und =[mapext_esc]= : Die vollen Extents der Karte, separiert durch Leerzeichen.  &lt;br /&gt;
*=[maxx]= , =[maxy]= , =[minx]=  und =[miny]= : Die einzelnen Koordinaten der Karte.  &lt;br /&gt;
*=[rawext]=  und =[rawext_esc]= : Die Extents der Karte, bevor sie auf die gewünschte Pixelgröße angepaßt worden ist, getrennt durch Leerzeichen.  &lt;br /&gt;
*=[rawmaxx]= , =[rawmaxy]= , =[rawminx]=  und =[rawminy]= : Die einzelnen Koordinaten der Extents der Karte, bevor die Karte auf die gewünschte Pixelgröße angepaßt worden ist.  &lt;br /&gt;
*=[maplon]=  und =[maplat]= : Längen- und Breitengrad des letzten Mausklicks in der Karte.  &lt;br /&gt;
*=[mapext_latlon]=  und =[mapext_latlon_esc]= : Voller Extent der Karte in Längen- und Breitengrade, separiert durch Leerzeichen.  &lt;br /&gt;
*=[minlon]= , =[minlat]= , =[maxlon]=  und =[maxlat]= : Die einzelnen Koordinaten der Extents der Karte in Längen- und Breitengraden.  &lt;br /&gt;
&lt;br /&gt;
Die folgenden Tags geben Aufschluss über die Layer in einer Karte:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[get_layers]= : Eine Aufzählung aller Layer, die in der aktuellen Karte aktiv sind, sodass sie in eine URL eingebunden werden können.    Zum Beispiel:    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  layer=fluesse&amp;amp;layer=eisenbahn&amp;amp;layer=seen  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    &lt;br /&gt;
*=[layers]=  und =[layers_esc]= : Die Namen aller aktiven Layer, voneinander durch Leerzeichen getrennt.    &lt;br /&gt;
*=[layername_check]=  und =[layername_select]= : Im Tag muß an dieser Stelle nicht 'layer' stehen, sondern der tatsächliche Name des Layers. Ist ein Layer aktiv, wird der Tag durch das Wort =checked=  bzw. =selected=  ersetzt. Auf diese Weise wird von Seitenaufruf zu Seitenaufruf mitgeschleift, ob ein Layer ausgewählt ist. Ein Beispiel für einen Layer namens 'fluesse':    &amp;lt;br&amp;gt;&amp;lt;code&amp;gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;layer&amp;quot; value=&amp;quot;fluesse&amp;quot;                                 [fluesse_select]&amp;gt; Flüsse  &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;    Wenn der Layer im URL angefordert worden ist, ist diese Checkbox automatisch selektiert.    &lt;br /&gt;
*=[layername_meta &amp;lt;data&amp;gt; &amp;lt;key&amp;gt;]= : Dieser Tag wird, genauso wie der entsprechende Tag in der Web-Sektion, durch Metadaten aus einem OGC-konformen Mapfile gefüllt.  &lt;br /&gt;
&lt;br /&gt;
Auch für das Zoomverhalten gibt es einige Tags für das Template:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[zoomdir_&amp;lt;-1|0|1&amp;gt;]=   &lt;br /&gt;
*=[zoom_minzoom to maxzoom_&amp;lt;select|check&amp;gt;]=   &lt;br /&gt;
&lt;br /&gt;
Zu guter Letzt natürlich noch die Tags, die für Queries interessant sind. Dementsprechend werden diese Tags nur dann ausgefüllt, wenn sie sich in einem Template befinden, das von einer Query abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=[shpext]= : Die Extents des Shapes, das das Suchergebnis darstellt.  &lt;br /&gt;
*=[shpminx]= , =[shpmaxx]= , =[shpminy]=  und =[shpmaxy]= : Dito, nur in die einzelnen Punktkoordinaten aufgeschlüsselt.  &lt;br /&gt;
*=[shpmid]= : Der Mittelpunkt eines gewähltes Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[shpmidx]=  und =[shpmidy]= : X- respektive y-Koordinate des Mittelpunkts.  &lt;br /&gt;
*=[shpidx]= : Index des aktuellen Shapefiles. Steht nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[tileindex]= : Index der momentanen Rasterkachel. Steht ebenfalls nur zur Verfügung, wenn Queries bearbeitet werden.  &lt;br /&gt;
*=[DBase column name]= : Jede beliebige Spalte einer ''.dbf'' -Datei kann in Query-Templates als Tag verwendet werden. Die entsprechenden Ergebnisse werden dann eingefügt.  &lt;br /&gt;
*=[cl]= : Name des aktuellen Layers. Sinnvoll in Layerheadern oder -footern.  &lt;br /&gt;
*=[lrn]= : Die Nummer eines Suchergebnisses im aktuellen Layer. Sinnvoll in Querytemplates.  &lt;br /&gt;
*=[nl]= : Anzahl der Layer, in denen es Suchergebnisse gegeben hat. Sinnvoll in Web-Headern oder -footern.  &lt;br /&gt;
*=[nlr]= : Gesamtzahl aller Ergebnisse im aktuellen Layer. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[nr]= : Gesamtzahl aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
*=[rn]= : Die Nummer des Suchergebnisses innerhalb aller Suchergebnisse. Sinnvoll in Web-Headern und -footern.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Metadaten=(21)\index{Mapfile!Metadaten}\index{Metadaten}&lt;br /&gt;
&lt;br /&gt;
Die Web-Sektion (und nicht nur diese) kann zwei Arten von Metadaten aufnehmen. Zum einen sind diejenigen Daten zu nennen, die für eine OGC-konforme Interaktion mit der Außenwelt sorgen. Wie mit diesen Daten umzugehen ist, erfahren Sie in Kapitel~\ref{text:ogc}.&lt;br /&gt;
&lt;br /&gt;
Des weiteren können Sie sozusagen &amp;quot;`freie&amp;quot;' Einträge vornehmen, die Sie dann -- in eckigen Klammern, siehe den nächsten Abschnitt über Templates -- als Parameter in das Template übernehmen und so in die HTML-Ausgabe einfügen können.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
METADATA&lt;br /&gt;
  autor   &amp;quot;Thorsten Fischer&amp;quot;&lt;br /&gt;
  adresse &amp;quot;Heilbronner Strasse 10&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Zeilen ermöglichen Ihnen, beispielsweise das folgende im Template zu tun:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Der Autor [autor] kann unter&lt;br /&gt;
   der Adresse [adresse] erreicht werden&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MapServer ersetzt diese Tags dann durch die Parameter aus der =METADATA= -Sektion.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass Sie solche Metadaten auch auf Layer-Ebene einfügen können. Diese Daten können Sie dann später beispielsweise dazu verwenden, die Layer in HTML-Legenden auf eine bestimmte Weise zu sortieren.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Idee zum Einsatz von Metadaten sind Links. Speichern Sie zum Layer gehörende URLs als Metadaten und fügen Sie sie später in Templates oder HTML-Legenden ein.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Queries=\index{Queries}\index{Mapfile!Queries}(22)&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man seine Daten nicht nur betrachten. Auch wenn es die größte Stärke des MapServer ist, schnell Karten generieren zu können und diese dann ausliefern zu lassen, ist eine minimale GIS-Funktion zuweilen wünschenswert. Die Anfragen auf die den Karten zugrundeliegenden Datenbestände werden beim MapServer ''Queries''  genannt.&lt;br /&gt;
&lt;br /&gt;
==Notation==&lt;br /&gt;
&lt;br /&gt;
Im HTML-Template, das das Benutzer-Interface für den MapServer definiert, muß natürlich zuerst die Möglichkeit geschaffen werden, neben dem Bewegen in der Karte auch Queries zuzulassen -- man muss zwischen beiden Modi wählen können. Das kann beispielsweise durch entsprechende Radio-Buttons passieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;browse&amp;quot; checked&amp;gt; Browsen&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;query&amp;quot;&amp;gt; Anfrage stellen&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Absenden des Formulars übermitteln die Radio-Buttons (wie man sie beispielsweise auch im offiziellen MapServer-Demo findet) den entsprechenden Modus an das MapServer-CGI.&lt;br /&gt;
&lt;br /&gt;
Möchte man mehrere Abfrageergebnisse zulassen, benötigt man den Modus =nquery= :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;mode&amp;quot; value=&amp;quot;nquery&amp;quot;&amp;gt; Mehrere Anfragen&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle drei Modi können natürlich im gleichen Formular vorkommen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren müssen Sie in allen Layern, für die Sie Abfragen zulassen möchten, ein =TEMPLATE=  definieren. Dabei können Sie einzelne Templates in den Classes des Layers definieren (die dann nur für Abfrageergebnisse der jeweiligen Klasse gelten) oder aber eine Angabe für den kompletten Layer machen; das muß dann außerhalb der Classes geschehen.&lt;br /&gt;
&lt;br /&gt;
Für die einfache Query wird außerdem nur der oberste sichtbare Layer der Karte befragt\footnote{Also der letzte sichtbare Layer im Mapfile}.&lt;br /&gt;
&lt;br /&gt;
Wie Templates für Abfrageergebnisse notiert werden, ist bereits in der umfänglichen Sektion über Templates beschrieben worden. Beachten Sie auf alle Fälle immer, ob Sie nur einfache oder multiple Ergebnisse bei Ihren Anfragen zulassen. Ist letzteres der Fall, sollten Sie sich über die Anordnung von =HEADER= - und =FOOTER= -Templates Gedanken machen.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel. Sie haben folgendes in Ihrem Layer notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;gemeinden&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  HEADER &amp;quot;gemeinden_head.html&amp;quot;&lt;br /&gt;
  FOOTER &amp;quot;gemeinden_foot.html&amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
  CLASS&lt;br /&gt;
    TEMPLATE &amp;quot;gemeinden.html&amp;quot;&lt;br /&gt;
  END&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für eine einfach Query würde lediglich einmal =gemeinden.html=  mit entsprechendem Ergebnis zurückgeliefert werden. Nehmen wir aber nun an, dass der Modues auf =nquery=  gesetzt ist, und mehrere Features mit einem Mausklick erwischt worden sind -- um ein Beispiel zu wählen: 3 Stück --, so wäre das Ergebnis wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
gemeinden_header.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden.html&lt;br /&gt;
gemeinden_footer.html&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das gleiche wiederholt sich dann noch für alle anderen Layer, die darunter liegen. Außerdem können für =nquery=  auch noch ein Header sowie ein Footer in der WEB-Sektion des Mapfiles definiert werden. Diese werden dann jeweils einmal dargestellt: einmal vor allen Suchergebnissen, und einmal dahinter.&lt;br /&gt;
&lt;br /&gt;
==Query maps==\index{Query map}(23)&lt;br /&gt;
&lt;br /&gt;
Querymaps sind kleine Karten, die in Ergebnistemplates dazu dienen, die Resultate von Queries zu visualisieren. Sie sind als eigene Sektion im Mapfile definiert, außerhalb jeder anderen Sektion (am besten nach dem Header) und sehen beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
QUERYMAP&lt;br /&gt;
  COLOR 255 0 0&lt;br /&gt;
  SIZE 200 200&lt;br /&gt;
  STATUS ON&lt;br /&gt;
  STYLE HILITE&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird eine 200x200 Pixel große Querymap erzeugt, in der angefragte Features rot markiert werden.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Optionen können in Querymap-Sektionen auftauchen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=COLOR &amp;lt;red&amp;gt; &amp;lt;green&amp;gt; &amp;lt;blue&amp;gt;=  Gibt die Farbe an, in der die angefragten Features markiert werden. Ergibt nur Sinn, wenn der =STYLE=  auf =HILITE=  gesetzt ist. Voreinstellung ist gelb.  &lt;br /&gt;
*=SIZE &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;=  Die Größe, in der die Querymap gezeichnet werden soll. Voreinstellung ist die Größe der Karte.  &lt;br /&gt;
*=STATUS &amp;lt;ON|OFF&amp;gt;=  Legt fest, ob die Querymap gezeichnet werden soll.  &lt;br /&gt;
*=STYLE &amp;lt;NORMAL|HILITE|SELECTED&amp;gt;=  Dieser Stil legt für den angefragten Layer fest, wie die gewählten Features gemalt werden sollen. =NORMAL=  zeichnet die Karte ohne Änderung. =HILITE=  zeichnet den Layer, markiert aber die gewählten Features mit der Farbe =COLOR= ; diese Art ist auch die Voreinstellung. =SELECTED=  zeichnet lediglich die gewählten Features.  &lt;br /&gt;
&lt;br /&gt;
Wie werden Querymaps nun dargestellt? Es gibt für diese Abfragekarten kein eigenes Schlüsselwort, vielmehr ändert sich der Tag =[img]= , wenn in einen Query-Modus geschaltet wird. Es wird dann nicht mehr die Karte, sondern eben die dazugehörige Abfragekarte dargestellt.&lt;br /&gt;
&lt;br /&gt;
Abgebildet wird in der Querymap der Ausschnitt der Karte, in dem man die Anfrage gestellt hat. Darin markiert sind die Abfrageergebnisse, wie man es im =QUERYMAP= -Block angegeben hat.&lt;br /&gt;
&lt;br /&gt;
Sie können übrigens eine Querymap auch separat von allem anderen mit dem Modus =querymap=  anfordern, genauso, wie auch eine normale =map= .&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Cached Queries}(24)\index{Queries!Cached Queries}\index{Cached Queries}&lt;br /&gt;
&lt;br /&gt;
Cached Queries sind eine Möglichkeit, Abfrageergebnisse abzuspeichern. Mit Cached Queries können Sie die Abfrageergebnisse in einer Karte darstellen, deren Extents Sie beliebig wählen können. Sie sind nicht auf den Ausschnitt beschränkt, an den die Anfrage gestellt wird.&lt;br /&gt;
&lt;br /&gt;
Um eine Cached Query benutzen zu können, müssen Sie zuerst eine weitere Zeile in Ihr HTML-Template aufnehmen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;savequery&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch werden nun bei Query-Aufrufen temporäre Dateien angelegt, wie es etwa auch für generierte Karten geschieht. Der Name dieser Datei läßt sich in einem Template nun mit Hilfe von Template-Tags rekonstruieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;[program]&amp;amp;map=[map]&amp;amp;&lt;br /&gt;
   queryfile=[map_image_path]&amp;lt;NAME&amp;gt;[id].qy&lt;br /&gt;
   [get_layers]&amp;amp;mode=map&amp;amp;size=200+200&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Wert =[map]=  wird sowieso immer übergeben, und =get_layers=  wird bei jedem Aufruf des MapServers automatisch aus den übergebenen Layern erstellt.\\ =map_image_path=  fügt der MapServer ebenfalls automatisch aus dem Mapfile ein. Der Wert von =[id]=  ist eine eindeutige ID für den jeweiligen MapServer-Aufruf und wird auch vom MapServer ausgefüllt. Der String =&amp;lt;NAME&amp;gt;=  ist der Wert, der im Mapfile als =NAME=  im Mapfile für die Karte gesetzt ist, und muß von Ihnen von Hand eingetragen werden.&lt;br /&gt;
&lt;br /&gt;
Der Trick ist nun, dieser Karte eine Bounding Box in bekannter Notation nach Ihrem Wunsch mitzugeben; man erhält somit beliebige Kartenausschnitte, in denen Abfrageergebnisse angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
==Joins==\index{Joins}&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke bei Joins entspricht dem gleichlautenden Begriff bei SQL-Da\-ten\-ban\-ken: die Inhalte zweiter Dateien mit Daten werden zu einem einzigen Datensatz zusammengefügt. Dazu benötigt man in beiden Datensätzen ein gemeinsames Datum, wie zum Beispiel eine ID, um den Inhalt den einen Datensatzes dem anderen zuordnen zu können.&lt;br /&gt;
&lt;br /&gt;
In MapServer kommt das Konzept vor allen Dingen zum Einsatz, um die Inhalte zweier DBF-Dateien zu einem einzigen zusammenzufügen, der dann dazu benutzt wird, die Expressions in Classes oder auch Query-Ergebnisse zu evaluieren. &lt;br /&gt;
&lt;br /&gt;
FIXME: funktioniert nicht?&lt;br /&gt;
&lt;br /&gt;
==Weitere Arten von Queries==&lt;br /&gt;
&lt;br /&gt;
Über die beiden Modi =query=  und =nquery=  hinaus definiert MapServer noch eine ganze Menge weiterer Typen für Datenanfragen. Auf einige dieser Modi soll hier noch im Detail eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
===indexquery===&lt;br /&gt;
&lt;br /&gt;
Eine Indexquery sucht ein Shape über seine ID im Shapefile heraus. Im Aufruf sieht das beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
http://www.example.com/cgi-bin/mapserv&lt;br /&gt;
  ? map=/pfad/zum/mapfile.map&lt;br /&gt;
  &amp;amp; mode=indexquery&lt;br /&gt;
  &amp;amp; qlayer=bundeslaender&lt;br /&gt;
  &amp;amp; shapeindex=15&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Aufruf dieser Art von Query erfolgt über den Modus =indexquery= . Der Layer, der das Ziel der Anfrage sein soll, wird mit =qlayer=  bestimmt.&lt;br /&gt;
&lt;br /&gt;
Für das Ergebnis dieses Aufrufs wird wie gewohnt das Template benutzt, das sie im entsprechenden Layer definiert haben (bzw. in den dortigen Classes). Anstatt aber nun die Koordinaten eines Mausklicks auszuwerten, wird gezielt nach einem bestimmten Shape gesucht. Das obige Beispiel zum Beispiel sucht nach dem sechszehnten Shape im Layer =bundeslaender= , und die Darstellung im Query-Template sieht dann dementsprechend aus.&lt;br /&gt;
&lt;br /&gt;
Falls Sie eine Querymap definiert haben sollten, so werden bei der Darstellung der Karte beim  obigen Aufruf die Extents verwendet, die im Mapfile definiert sind. Der CGI-Parameter =mapext=  kann verwendet werden, um wie im Modus =browse=  einen anderen Kartenausschnitt festzulegen. Falls Sie diesen Parameter nicht auf bestimmte Werte setzen, sondern stattdessen =mapext=shapes=  verwenden, wird direkt auf das Ergebnisshape gezoomt.&lt;br /&gt;
&lt;br /&gt;
Nur die Querymap als Bild können Sie sich übrigens mit dem Modus =indexquerymap=  zurückliefern lassen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zu den Parametern im gezeigten Beispielaufruf gibt es auch noch =tileindex= , für den Fall, dass sie gekachelte Shape-Daten verwenden.&lt;br /&gt;
&lt;br /&gt;
===itemquery und itemnquery===&lt;br /&gt;
&lt;br /&gt;
Durch eine Itemquery können Sie Features anhand von nichträumlichen Eigenschaften auswählen. Bei Daten aus Shapefiles (auf die wir uns hier konzentrieren wollen) kommen diese Eigenschaften selbstverständlich aus den =.dbf= -Dateien.&lt;br /&gt;
&lt;br /&gt;
Um über den URL auf diese Eigenschaften zugreifen zu können, müssen wir sie mit einem Namen bekannt machen. Dazu benutzen wir den Parameter =FILTER=  im entsprechenden Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  ...&lt;br /&gt;
  DATA &amp;quot;bundeslaender&amp;quot;&lt;br /&gt;
  FILTERITEM &amp;quot;NAME&amp;quot;&lt;br /&gt;
  FILTER &amp;quot;&lt;br /&gt;
  ...&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel verwenden wir die DBF-Tabellenspalte =NAME=  und machen sie nach außen als =name=  bekannt.&lt;br /&gt;
&lt;br /&gt;
Zugriff erhalten wir nun über diesen Namen. Im URL notieren wir jetzt folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FIXME&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FIXME:mehr&lt;br /&gt;
&lt;br /&gt;
Da diese Art von Query mit Angabe einer Zeichenkette funktioniert, ist es in den meisten Fällen sinnvoll, dem Benutzer eine Auswahlliste zur Verfügung zu stellen, aus der er sich dann Features nach Namen auswählen kann.&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
===featurequery und featurenquery===&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.55}{featurenquery-berlin}{Eine =featurenquery= . Hier wurde das Bundesland Berlin gewählt und nach allen Features (Postleitzahlgebieten und bestimmte Kacheln) gefragt, die von der Fläche des Bundeslandes geschnitten werden.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
In diesem Modus wird ein Feature ausgewählt, und alle dafür eingestellten Layer werden befragt, welche Features durch dieses Feature geschnitten werden. Sie können ein Beispiel dafür in Abbildung~\ref{featurenquery-berlin} sehen: Hier wurde das Bundesland Berlin durch einen Mausklick ausgewählt, und das Ergebnis ist eine Liste aller Features, die die Fläche eben dieses Bundeslandes schneiden.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie bitte, dass wir an dieser Stelle nur die Fassung dieser Query mit dem =n=  im Namen betrachten. =featurequery=  funktioniert analog zum Paar =query= /=nquery=  mit nur einem einzigen Suchergebnis.&lt;br /&gt;
&lt;br /&gt;
Als erstes benötigen Sie für diese Art von Query selbstverständlich einen entsprechenden Modus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; mode = featurenquery &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muß spezifiziert werden, anhand welchen Layers die Auswahl getroffen werden soll. Vorstellbar wäre zum Beispiel eine Auswahlbox mit einer Liste aller Layer, aus der dann ein Layer als Bezugsebene ausgewählt werden kann. Der zuständige Parameter heißt =slayer= . Heißt der Layer beispielsweise =gruenflaechen= , so notiert man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
... &amp;amp; slayer = gruenflaechen &amp;amp; ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeder Layer, der über =layer==  im URL spezifiziert wird und ein =TEMPLATE=  gesetzt hat, wird nun für den Vergleich herangezogen.&lt;br /&gt;
&lt;br /&gt;
Das Abarbeiten der Query-Templates läuft in der gewohnten Weise ab; für jedes Ergebnis in einer Class werden die Templates hintereinander gehangen, für den Layer dann eventuell noch Header davor und Footer dahinter, und um das ganze herum dann eventuell vorhandene Header und Footer aus der Web-Sektion.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Zum Zeitpunkt der Drucklegung funktionierte diese Art von Query nicht mit umprojizierten Daten. Quell- und Zielprojektion mußten übereinstimmen, um Suchergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
===itemfeaturequery und itemfeaturenquery===&lt;br /&gt;
&lt;br /&gt;
FIXME&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=PostgreSQL und PostGIS=&lt;br /&gt;
\index{PostGIS}\index{PostgreSQL}&lt;br /&gt;
&lt;br /&gt;
PostGIS, ein Zusatz für die freie Datenbank PostgreSQL, ist die 'Standard'-Daten\-bank\-an\-bindung für den MapServer. PostGIS setzt einen großen Teil der Simple Features des OGC um und kann nicht nur als Datenquelle für den MapServer dienen, sondern generell raumbezogene SQL-Anfragen verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Die Anbindung einer PostGIS-Datenbank wird in Kapitel~\ref{text:database} ab Seite~\pageref{text:database:postgis} beschrieben.&lt;br /&gt;
&lt;br /&gt;
=OGR=\index{OGR}(25)&lt;br /&gt;
&lt;br /&gt;
Die OGR-Bibliothek ist das vektor-orientierte Gegenstück zu GDAL. Obwohl es sich um eine eigenständige Bibliothek handelt, wird sie zusammen mit GDAL ausgeliefert.&lt;br /&gt;
&lt;br /&gt;
Neben den Shapefiles gibt es nämlich noch eine ganze Reihe anderer Vektorformate. Shapefiles sind so ziemlich das minimalistischste, was man sich vorstellen kann, sie beinhaltet lediglich die Koordinaten von Punkten. Viele Vektorformate sind allerdings etwas komplexer, und enthalten gleich mehrere Datensätze, einen Haufen zusätzliche Metadaten oder gleich Informationen über die Gestaltung der Daten.&lt;br /&gt;
&lt;br /&gt;
Besonders bei der letztgenannten Klasse von Formaten sollte man vorsichtig sein und von OGR nicht zuviel erwarten. Zwar gibt es für diese Formate die Möglichkeit, das Layout der Daten auszulesen, aber nicht immer kann diese Information auch umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Von der Notation her gibt es, ähnlich wie bei Datenanbindungen, nur eine grundlegende Änderung: Im Layer wird nun nicht mehr =DATA=  als Schlüsselwort für die Datenquellen verwendet, sondern die beiden Parameter =CONNECTIONTYPE=  (dieser ist dann immer =OGR= ) und =CONNECTION= . Dabei wird =CONNECTION=  dann von den notwendigen Details wie dem gewünschten Layer aus dem Datensatz usw. gefolgt.&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
=Spezifikation von Ausgabeformaten=(26)&lt;br /&gt;
&lt;br /&gt;
Mit Version 4.0 des MapServers ist man nun endlich in der Lage, mehrere verschiedene Ausgabeformate für die fertige Karte zu spezifizieren. Bisher war man auf ein einziges Rasterbild-Format festgelegt (PNG respektive GIF).&lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
Ein Mapfile kann eine, mehr als eine oder sogar gar keine OUTPUTFORMAT-Sektion haben. Ohne jede Angabe wird bei einkompilierter GD-Bibliothek ein PNG-Bild zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
Eine OUTPUTFORMAT-Sektion sieht typischerweise so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;png&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/PNG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/png&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;png&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst erhält die Sektion einen Namen. Danach wird ein &amp;quot;Treiber&amp;quot; für die Erstellung des Bildes angegeben. Für die typische PNG-Ausgabe mit der Bibliothek GD steht hier ''GD/PNG'' .&lt;br /&gt;
&lt;br /&gt;
Der Mimetype ist wichtig, um dem Browser, der die fertige Karte entgegennimmt, mizuteilen, welcher Art die Daten sind, die da ankommen\footnote{Für Windows-Benutzer: Nein, der Dateiname sagt nichts über die Art einer Datei aus. Er ist im Grunde nicht einmal Bestandteil einer Datei. Microsoft hat das aber schon vor einer ganzen Weile vergessen.}. Er ist für diese Sektion allerdings Optional, da MapServer auch versucht, ihn automatisch zu bestimmen.&lt;br /&gt;
&lt;br /&gt;
Der IMAGEMODE gibt unter anderem die Farbtiefe des Bildes an (siehe die Sektion über Rasterbilder; ist aber auch für Flash relevant), und schließlich die Dateinamenerweiterung des Outputs.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen für die verschiedenen Anwendungsfälle alle möglichen Optionen in der OUTPUTFORMAT-Sektion angegeben werden.&lt;br /&gt;
&lt;br /&gt;
==Rasterbilder==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es gibt es nur zwei Treiber für Rasterbildformate im MapServer: die inzwischen klassische Ausgabe mittels GD, und ganz neu GDAL. Letzteres kann bisher nur GeoTIFF-Bilder produzieren, aber es ist ein Anfang.&lt;br /&gt;
&lt;br /&gt;
FIXME: blah&lt;br /&gt;
&lt;br /&gt;
Der Parameter =IMAGEMODE=  sagt aus, in welcher Farbtiefe das Bild produziert werden soll, und wie Transparenzen gehandhabt werden sollen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=PC256= : Produziert ein Bild mit einer eigenständigen Farbpalette mit (maximal) 256 Farben. Dies ist der klassische MapServer-Modus. Der Raster-Treiber ''GD/GIF''  kennt ausschließlich diesen Modus. TRansparenz ist mit diesem Modus möglich.  &lt;br /&gt;
*=RGB= : 24-Bit RGB-Farbbild. Ohne Transparenz.  &lt;br /&gt;
*=RGBA= : 32-Bit RGBA-Farbbild mit Alphakanal (Transparenz).  &lt;br /&gt;
*FIXME: mehr?  &lt;br /&gt;
&lt;br /&gt;
Über alle diese Optionen hinaus gibt es noch treiberabhängige Angaben, die sogenannten FORMATOPTIONs. Sie werden folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;jpg&amp;quot;&lt;br /&gt;
  DRIVER &amp;quot;GD/JPEG&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;image/jpeg&amp;quot;&lt;br /&gt;
  IMAGEMODE RGB&lt;br /&gt;
  EXTENSION &amp;quot;jpg&amp;quot;&lt;br /&gt;
  FORMATOPTION &amp;quot;QUALITY=75&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes OUTPUTFORMAT kann dabei keine, eine oder mehrere (passende!) Angaben für FORMATOPTIONs haben. Im folgenden sind alle diese Optionen für die einzelnen Treiber beschrieben.&lt;br /&gt;
&lt;br /&gt;
===Der GD-Treiber===&lt;br /&gt;
&lt;br /&gt;
Der GD-Treiber kennt die folgenden, optionalen Parameter in der OUTPUTFORMAT-Sektion:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=QUALITY=  Legt für JPEG-Bilder die Kompression fest. Liegt zwischen =0=  (niedrigste Qualität, höchste Kompression) und =100=  (höchste Qualität, niedrigste Komprimierung).  &lt;br /&gt;
*=INTERLACE=  Legt fest, ob PNG- bzw. GIF-Bilder interlaced sein sollen (=ON= ) oder nicht (=OFF= ).  &lt;br /&gt;
&lt;br /&gt;
FIXME: mehr&lt;br /&gt;
&lt;br /&gt;
===Der GDAL-Treiber===&lt;br /&gt;
&lt;br /&gt;
Generell kann man dem GDAL-Treiber alles als Parameter mitgeben, was die Bibliothek als Optionen kennt; was alles in Frage kommt, erfahren Sie in der Dokumentation von der Website~[[http:website:gdal]].&lt;br /&gt;
&lt;br /&gt;
FIXME: vervollständigen!1!&lt;br /&gt;
&lt;br /&gt;
==Vektorformate==(27)&lt;br /&gt;
&lt;br /&gt;
Vektorausgabeformate sind ein neues Feature in MapServer 4.0. Die Fülle von Einstellungen, die man dabei theoretisch machen kann, wird durch die Einführung von =OUTPUTFORMAT=  abgefangen. &lt;br /&gt;
&lt;br /&gt;
Alle bisher unterstützten Vektorformate zeichnen sich durch die Eigenschaft aus, dass sie nicht von sich aus im Browser darstellbar sind, sondern eine zusätzliche Bearbeitung oder doch zumindest den Einsatz von separaten Plugins im Webbrowser notwendig machen.&lt;br /&gt;
&lt;br /&gt;
Wachsender Beliebtheit bei den Vektorformaten im Web erfreut sich auch SVG, ein XML-basiertes Format. Folglich sind Fragen nach einer Unterstützung für dieses Format auf der Mailingliste an der Tagesordnung. Bisher hat sich aber noch niemand die Mühe gemacht, Unterstützung für dieses Format zu implementieren. Das kann sich im Laufe der Zeit selbstverständlich ändern.&lt;br /&gt;
&lt;br /&gt;
===PDF===&lt;br /&gt;
&lt;br /&gt;
Unterstützung für die Ausgabe von PDF-Dateien wird mit der Bibliothek PDFLib realisiert. Dafür wird MapServer beim Kompilieren ganz einfach gegen diese Bibliothek gelinkt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgabeformat wird recht simpel folgendermaßen notiert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;pdf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/pdf&amp;quot;&lt;br /&gt;
  DRIVER PDF&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da man PDF nicht einfach über einen =&amp;lt;img&amp;gt;= -Tag in seine HTML-Seite einbinden kann, bietet sich ein anderes Vorgehen an. Man baut ein Template zum Browsen der Karte wie gewohnt, gibt dem Benutzer aber noch einen Link mit einer Beschriftung wie 'diese Karte als PDF herunterladen' mit auf den Weg. Diesen Link kann man sich für den aktuellen Kartenausschnitt mit den entsprechenden MapServer-Tags bauen, zum Beispiel wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;/cgi-bin/mapserv?map=[map]&amp;amp;imgext=[mapext]&amp;amp;FIXME=pdf ...&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Liste der Parameter ist hier nicht vollständig, aber die Idee wird klar.&lt;br /&gt;
&lt;br /&gt;
Wer den Verlauf der Entwicklung von MapServer 4.0 mitverfolgt hat, hat vielleicht mitbekommen, dass zu Beginn der PDF-Unterstützung lediglich ein PNG-Bild erzeugt worden ist, das dann in ein PDF-Dokument eingebettet wurde. Das ist nicht mehr der Fall, nun liefert MapServer für Vektordaten richtiges PDF zurück.&lt;br /&gt;
&lt;br /&gt;
Wenn man eine Weile mit diesem Ausgabeformat experimentiert, wird man merken, dass die reine Ausgabe einfach nur einer Karte im PDF-Format recht unbefriedigend ist. Wer gestalterisch tätig werden möchte, der muß mit einer Skriptsprache Hand anlegen.&lt;br /&gt;
&lt;br /&gt;
''Hinweis'' : Beachten Sie bitte unbedingt, dass die Nutzung für die hier verwendete Bibliothek PDFLib nicht für ausnahmslos alle Nutzungen kostenlos ist. Bitte informieren Sie sich auf der Website~[[http:website:pdflib]] der Bibliothek über die Details.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist die Erzeugung von PDF eine recht rechenintensive Sache, deren Einsatz man demnach mit Bedacht planen sollte.&lt;br /&gt;
&lt;br /&gt;
===Shockwave Flash===&lt;br /&gt;
&lt;br /&gt;
Flash ist ein Vektorformat, das im Web vor allen Dingen dafür verwendet wird, Animationen darzustellen. Daher spricht man bei einem Flash-Element in einer Website gewöhnlich von einem 'Movie', sogar dann, wenn es sich eigentlich um statischen Inhalt handelt. MapServer bietet mit Version 4.0 nun auch die Möglichkeit, fertige Karten als Flash-Movies auszuliefern.&lt;br /&gt;
&lt;br /&gt;
Dabei stützt sich MapServer auf die Bibliothek Ming~[[http:website:ming]], die im Moment von Wolfgang Hamann weiterentwickelt wird, nachdem er diese Aufgabe im November 2002 vom ursprünglichen Entwickler übernommen hat\footnote{Leider hat sie im Laufe der Zeit keine Updates mehr erfahren.}. Die Software zeichnet sich insbesondere durch ihre vielfältigen Bindungen an andere Programmiersprachen aus.&lt;br /&gt;
&lt;br /&gt;
Die Installation für Flash-Unterstützung wird für das Selberkompilieren von Binaries ab Seite~\pageref{anhang:installation:compile:flash} besprochen.&lt;br /&gt;
&lt;br /&gt;
Es gibt für uns zwei Arten, Flash-Output zu generieren: einmal einen Movie für die komplette Karte, und einmal einen Movie für jede einzelnen Layer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
OUTPUTFORMAT&lt;br /&gt;
  NAME &amp;quot;swf&amp;quot;&lt;br /&gt;
  MIMETYPE &amp;quot;application/x-shockwave-flash&amp;quot;&lt;br /&gt;
  DRIVER swf&lt;br /&gt;
  IMAGEMODE PC256&lt;br /&gt;
  FORMATOPTION &amp;quot;OUTPUT_MOVIE=SINGLE&amp;quot;&lt;br /&gt;
  # FORMATOPTION &amp;quot;OUTPUT_MOVIE=MULTIPLE&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie mit diesem =OUTPUTFORMAT=  einen Aufruf durchführen, werden Sie feststellen, dass Sie eine Datei (oder mehrere, wenn Sie =MULTIPLE=  statt =SINGLE=  im Beispiel gewählt haben) mit der Endung =.swf=  in Ihrem temporären Verzeichnis aufgetaucht ist.&lt;br /&gt;
&lt;br /&gt;
Bevor Sie diese Dateien tatsächlich benutzen können, müssen Sie sich aber noch ein wenig Arbeit machen. Was Sie benötigen, ist Kenntnis in der Sprache ActionScript, und ein Flash-SDK. Leider würde es den Rahmen dieses Buches sprengen, das eine oder das andere zu erläutern. Daher bleibt mir nur der Verweis auf das Archiv der MapServer-Mailingliste, wo Sie auf der Suche nach Beispielapplikationen und Diskussionen fündig werden können.&lt;br /&gt;
&lt;br /&gt;
=Features=(28)&lt;br /&gt;
&lt;br /&gt;
Für manche Dinge ist es nicht nötig -- oder schlicht zu aufwendig -- ein eigenes Shapefile oder eine andere Datenquelle zu haben. Sie können einfache Features auch als =FEATURE= -Block direkt im Mapfile notieren. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
FEATURE&lt;br /&gt;
  POINTS&lt;br /&gt;
    1 1&lt;br /&gt;
    10 10&lt;br /&gt;
    10 1&lt;br /&gt;
    1 1&lt;br /&gt;
  END&lt;br /&gt;
  TEXT &amp;quot;Dreieck&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier definieren wir ein Dreieck in der linken oberen Ecke der fertigen Karte. Der Parameter =TEXT=  definiert die Beschriftung des Features.&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass für einen geschlossenen Linienzug der letzte Punkt dem ersten Punkt entsprechen muß. Für die Einbettung eines =FEATURE=  in einen Layer schauen Sie sich bitte den nächsten Abschnitt an.&lt;br /&gt;
&lt;br /&gt;
==Fix positionierte Elemente==&lt;br /&gt;
&lt;br /&gt;
Zuweilen möchte man in eine fertige Karte noch eine Information einfügen, die immer gleich bleibt; ein Logo, eine Urhebernotiz, was auch immer. Das Problem ist natürlich, dass bisher immer alles georeferenziert war und daher immer auf einen bestimmten Punkt fixiert.&lt;br /&gt;
&lt;br /&gt;
\begin{figure}&lt;br /&gt;
\begin{center}&lt;br /&gt;
\mmfig{0.60}{transform-label}{Ein fixes Label in einer Karte, hier der URL der MapMedia-Website.}&lt;br /&gt;
\end{center}&lt;br /&gt;
\end{figure}&lt;br /&gt;
&lt;br /&gt;
Mit dem Parameter =TRANSFORM=  in einem Layer können Sie dieses Verhalten jedoch ein wenig manipulieren. Dieser Parameter gibt an, ob das Koordinatensystem der Datenquelle im Verhältnis zum fertigen Bild transformiert werden soll oder nicht. Die Standardeinstellung ist immer =TRUE= , was nicht weiter verwundert, denn bisher wurde immer das Koordinatensystem der Daten in das Koordinatensystem des Bildes (Angabe in Pixeln und Ursprung links oben) umgewandelt.&lt;br /&gt;
&lt;br /&gt;
Setzen Sie diesen Wert jedoch auf =FALSE= , können Sie neue Dinge tun, unter anderem auch mit einer =FEATURE= -Sektion, beispielsweise wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
LAYER&lt;br /&gt;
  NAME &amp;quot;credits&amp;quot;&lt;br /&gt;
  STATUS DEFAULT&lt;br /&gt;
  TRANSFORM FALSE&lt;br /&gt;
  TYPE ANNOTATION&lt;br /&gt;
  FEATURE&lt;br /&gt;
    POINTS&lt;br /&gt;
      10 10&lt;br /&gt;
    END&lt;br /&gt;
    TEXT 'http://www.mapmedia.de/'&lt;br /&gt;
  END&lt;br /&gt;
  CLASS&lt;br /&gt;
    LABEL&lt;br /&gt;
      TYPE TRUETYPE&lt;br /&gt;
      FONT &amp;quot;arial&amp;quot;&lt;br /&gt;
      SIZE 11&lt;br /&gt;
      ANTIALIAS TRUE&lt;br /&gt;
      COLOR 0 0 0&lt;br /&gt;
    END&lt;br /&gt;
  END&lt;br /&gt;
END																					 &lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Layer besteht aus nur einem Feature, einem Punkt, dessen Koordinaten fest angegeben sind, und ebenso seine Beschriftung. In der dazugehörigen Class ist die Beschriftung mit Schriftart, Farbe usw. definiert. Dadurch, dass der Status auf =DEFAULT=  gesetzt ist, und dass man diesen Layer als letzten Layer im Mapfile notiert, hat man einen Effekt wie in Abbildung~\ref{transform-label}: eine Beschriftung, die immer in der Karte zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
FIXME: raster?&lt;br /&gt;
&lt;br /&gt;
=CGI-Parameter=(29)&lt;br /&gt;
&lt;br /&gt;
FIXME:aufzählung&lt;br /&gt;
&lt;br /&gt;
==Parameter einschränken==(30)&lt;br /&gt;
&lt;br /&gt;
FIXME:Restriktion durch eine EXPRESSION&lt;br /&gt;
&lt;br /&gt;
\subsection*{Ändern des Mapfiles}&lt;br /&gt;
&lt;br /&gt;
Von außen (über den aufrufenden URL) können auch praktisch alle Inhalte des Mapfiles verändert werden. Der Aufbau dieser neuen Parameter ist recht simpel und orientiert sich an der Struktur eines Mapfiles.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir den Aufbau eines Mapfiles: eine Map beinhaltet (mindestens einen) Layer, dieser mindestens eine Klasse (wenn es sich um einen Vektorlayer handelt). Diese Klasse kann nun wiederum ein Label beinhalten, welches seinerseits eine Farbe hat.&lt;br /&gt;
&lt;br /&gt;
Die Adressierung kann auf verschiedene Weise geschehen. Zuerst einmal über Nummern. Im folgenden Beispiel bekommt die erste Klasse im zweiten Layer die Farbe Rot zugewiesen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_layer_1_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das '\&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus lassen sich Layer auch über ihren Namen referenzieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_fluesse_class_0_color=255&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Layer nur eine Klasse hat, sollte man den Index einfach weglassen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren lassen sich auf diesem Weg simple Features zu einem Layer hinzufügen. Der Layer muß existieren. Hier das Beispiel aus der offiziellen MapServer-Dokumentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
...&amp;amp;map_user_feature=new&amp;amp;map_user_feature_points=12345.6789+12345.6789&lt;br /&gt;
   &amp;amp;map_user_feature_text=My+House!&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dem Layer ''user''  wird auf diese Weise ein Punkt mit den angegebenen Koordinaten hinzugefügt, und er wird auch gleich beschriftet. Wird ein Layername mehrfach verwendet, wird das Feature einfach erweitert. Auf diese Weise lassen sich beispielweise Polygone mit 'Löchern' hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=Logs=(31)&lt;br /&gt;
&lt;br /&gt;
Für einen Serverdienst möchte man selbstverständlich Log-Dateien angelegt bekommen. Ein Server läuft die ganze Zeit vor sich hin, sodass man, im Gegensatz zu einer Desktop-Anwendung, im Fehlerfall meistens nicht anwesend ist. Dann sind Protokolle der Serveraktivitäten natürlich notwendig für die Fehlersuche.&lt;br /&gt;
&lt;br /&gt;
Aber auch für den Entwickler sind Logfiles wichtig, zeigen sie ihm doch, wo er nach Ursachen zu suchen hat, wenn sich die Anwendung, an der er arbeitet, nicht so verhält wie erwartet.&lt;br /&gt;
&lt;br /&gt;
Wofür auch immer man seine Logs verwendet, definiert wird die Logdatei in MapServer in der Web-Sektion:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
WEB&lt;br /&gt;
  ...&lt;br /&gt;
  LOG &amp;quot;/pfad/zur/datei.log&amp;quot;&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt nur eine einzige Logdatei pro Mapfile, in der MapServer sowohl Fehlermeldungen als auch erfolgreiche Zugriffe loggen kann.&lt;br /&gt;
&lt;br /&gt;
Das Format für Logfiles ist leider nict dokumentiert, sodass man sich mit einem Blick in den Quellcode weiterhelfen muß\footnote{Siehe Funktion =writeLog=  in =mapserv.c= }. Ein Eintrag in einem Logfile sieht beispielsweise folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;&lt;br /&gt;
Fri Mar 21 16:02:48 2003,1031,10.0.1.2,demonstration,0, \&lt;br /&gt;
7.848750 49.445625 19.098750 55.070625,13.473750 52.258125, \&lt;br /&gt;
bundeslaender,normal execution&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So ein Eintrag erstreckt sich immer über eine einzelne Zeile. Alle Bestandteile sind durch Kommata voneinander getrennt. Die vorliegende Zeile ist im einzelnen wie folgt zu verstehen:&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
*=Fri Mar 21 16:02:48 2003=  Ist ein Zeitstempel; Datum und Uhrzeit des Aufrufs.  &lt;br /&gt;
*=1031=  Die aktuelle Prozess-ID.  &lt;br /&gt;
*=10.0.1.2=  Die IP-Adresse des aufrufenden Hosts. Wird aus der Umgebungsvariable =REMOTE_ADDR=  gelesen und ist =NULL= \footnote{Hier ist die Zeichenkette ='NULL'=  gemeint}, wenn diese Variable nicht gesetzt ist.  &lt;br /&gt;
*=demonstration=  Der Name des Mapfiles, wie er mit =NAME=  im Header gesetzt ist.  &lt;br /&gt;
*=0=  Der Modus des Aufrufes, also z.B. =map= , =browse=  und so weiter. Es gibt 26 verschiedene, die allesamt in =maptemplate.h=  in einem Aufzählungstyp definiert sind.  &lt;br /&gt;
*=7.848750 49.445625 19.098750 55.070625=  sind die Extents des angezeigten Kartenausschnitts.  &lt;br /&gt;
*=13.473750 52.258125=  Ist der Punkt in der Karte, der angeklickt worden ist. Dieser Punkt hat den Aufruf des MapServers verursacht.  &lt;br /&gt;
*=bundeslaender=  Eine Liste der angeforderten Layer, durch Leerzeichen voneinander getrennt.  &lt;br /&gt;
*=normal execution=  Ist alles glatt gelaufen, findet sich dieser Eintrag am Ende einer Zeile.  &lt;br /&gt;
&lt;br /&gt;
Für ausführlicheres Logging gibt es den Parameter =DEBUG= , der im Header, in Layern und in Classes definiert werden kann. Mit dieser Einstellung produzieren bisher allerdings im wesentlichen nur Raster- und WMS-konforme Layer ausführlichere Fehlermeldungen. Es steht zu erwarten, dass dieser Parameter noch weiter ausgebaut wird.&lt;br /&gt;
&lt;br /&gt;
\subsubsection*{Log-Dateien im Webserver}&lt;br /&gt;
&lt;br /&gt;
Neben den Logs des MapServers haben Sie im Fehlerfall natürlich immer noch die Logs Ihres Webservers zur Verfügung. Im Fehlerfall finden Sie hier auch die HTTP-Fehlercodes, die dann nützlich sind, wenn es nicht MapServer-Fehler sind, die Ihnen Probleme bereiten. Insbesondere bei der Apache-Fehlermeldung ''Internal Server Error''  finden Sie normalerweise detaillierte Einträge, die Ihnen helfen können, die Ursache des Problems schnell zu lokalisieren.&lt;br /&gt;
&lt;br /&gt;
=Logging=&lt;br /&gt;
&lt;br /&gt;
Mit Mapserver 5.0 wurden die Möglichkeiten des Loggings erheblich erweitert. Zur Konfiguration sind zwei Punkte zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Die Variable MS_ERRORFILE muss gesetzt werden.&lt;br /&gt;
* Auf Map- bzw. Layer-Ebene wird ein Debuglevel gesetzt&lt;br /&gt;
&lt;br /&gt;
'''''MS_ERRORFILE &amp;lt;Wert&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Die Variable MS_ERRORFILE kann entweder mittels Umgebungsvariable oder per CONFIG-Direktive in dem Mapfile gesetzt werden. Die CONFIG-Direktive hat dabei Vorrang, falls beide Möglichkeiten genutzt werden. &lt;br /&gt;
Hiermit wird angegeben wohin die Logmeldungen geschrieben werden. Je nach Wert gibt es ''folgende Werte'':&lt;br /&gt;
; stderr : Ausgabe wird an die Standardfehlerausgabe gesandt. Bei Apache ist dies die per error_log angegebene Datei. Beim IIS wird es per Standardausgabe ausgegeben.&lt;br /&gt;
; stdout : Ausgabe wird an die Standardausgabe gesandt&lt;br /&gt;
; windowsdebug : Ausgabe wird an die Windows OutputDebugString API gesandt. Dadurch kann mit Programmen wie Debugview (Microsoft/Sysinternals) die Ausgabe verfolgt werden.&lt;br /&gt;
; PFAD : eine absolute Pfadangabe zum Logfile&lt;br /&gt;
&lt;br /&gt;
Wird diese Variable nicht gesetzt, ist das Logging deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;/Pfad/zum/Logfile&amp;quot; &lt;br /&gt;
&lt;br /&gt;
oder&lt;br /&gt;
&lt;br /&gt;
 CONFIG &amp;quot;MS_ERRORFILE&amp;quot; &amp;quot;stderr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dabei sollten Pfade immer als absoluter Pfad angegeben werden.&lt;br /&gt;
&lt;br /&gt;
'''''DEBUG &amp;lt;level&amp;gt;'''''&lt;br /&gt;
&lt;br /&gt;
Das DEBUG-Level wird entweder global oder auf Layerebene gesetzt. Zur Verfügung stehen ''folgende 6 Level'':&lt;br /&gt;
; Level 0 : Es werden ausschließlich Fehler geloggt. Entspricht DEBUG OFF bzw. DEBUG 0&lt;br /&gt;
; Level 1 : zusätzlich Warnungen zu nicht-fatalen Fehlern wie z.B. fehlende oder falsche Werte für bestimmte Parameter, fehlende Shapefiles in tileindex oder Zeitüberschreitung bei externen WMS-Diensten&lt;br /&gt;
; Level 2 : zusätzlich Hinweise mit Zeitinformationen &lt;br /&gt;
; Level 3 : zusätzlich Debugausgaben wie WMS-Verbindungs-URLs, Datenbank-Verbindungs-Informationen usw.&lt;br /&gt;
; Level 4 : weitere Ausgaben&lt;br /&gt;
; Level 5 : detaillierte Informationen die für Entwickler gedacht sind  &lt;br /&gt;
&lt;br /&gt;
Das Debuglevel kann global entweder per Umgebungsvariable MS_DEBUGLEVEL oder im Mapfile gesetzt werden. Werden beide Möglichkeiten genutzt, hat die Angabe im Mapfile Vorrang. Bei der Ausgabe wird für jeden Layer das gleiche Debuglevel genutzt.&lt;br /&gt;
Das Debuglevel auf Layerebene überschreibt ein evtl. gesetztes globales Debuglevel. Dadurch kann bis auf Layerebene die Fehlerausgabe individuell eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Wird die Umgebungsvariable benutzt so werden auch Meldungen z.B. zur Initialisierung ausgegeben die außerhalb von Layer- oder Map-Context erfolgen.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
&lt;br /&gt;
Bei manchen Projekten kann das Mapfile sehr groß werden. Durch die INCLUDE-Direktive kann man die Übersichtlichkeit wieder erhöhen, in dem man einzelne Abschnitte in separate Dateien auslagert. Für hochperformante Mapserveranwendungen wird dieses Vorgehen nicht empfohlen, da ein gewisser Overhead entsteht. Eine Standardanwendung wird bei Verwendung von INCLUDE-Direktiven nicht spürbar verlangsamt.&lt;br /&gt;
&lt;br /&gt;
Beispielaufruf:&lt;br /&gt;
&lt;br /&gt;
 INCLUDE &amp;quot;basislayer.map&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Folgende Hinweise sind bei der Verwendung zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Der Name der Datei '''sollte''' in Anführungszeichen stehen&lt;br /&gt;
* Die maximale Verschachtelungtiefe beträgt 5&lt;br /&gt;
* Die Pfadangabe kann absolut oder relativ zum Mapfile erfolgen&lt;br /&gt;
* Die Fehlerverfolgung wird erschwert da z.B. die angegebene Zeilennummer ggf. nicht mehr stimmt&lt;br /&gt;
&lt;br /&gt;
[[Category:UMN MapServer Handbuch]]&lt;/div&gt;</summary>
		<author><name>Wiki-Mikee63</name></author>
	</entry>
</feed>