Kartenmacher
Der Mapserver der Universität von Minnesota eignet sich nicht nur zum Bereitstellen eigener Daten, sondern auch zur Verwaltung von Geodatendiensten. Dabei erweist sich die Programmierschnittstelle Mapscript-API als große Hilfe.
- Jens Schumacher
Standardisierte Geodatendienste anzubieten ist für viele Unternehmen und öffentliche Einrichtungen zunehmend wichtiger, da diese die Kernkomponenten in wachsenden und flexiblen Geodateninfrastrukturen bilden. Der Mapserver der Universität von Minnesota (UMN) [1] bietet durch seine Mapscript-API einen effizienten Weg, Geodatendienste zu veröffentlichen.
Beim Austausch von Geodaten kommen verstärkt standardisierte Dienste zum Einsatz. Das resultierende Netz aus Datenanbietern und -konsumenten im Verbund mit der eingesetzten Technik bezeichnet man als Geodateninfrastruktur. Solche Infrastrukturen haben sich vor allem in der öffentlichen Verwaltung auf verschiedenen räumlichen und hierarchischen Ebenen etabliert, etwa das europäische INSPIRE oder die deutschlandweite GDI-DE.
Dienstbasierte Infrastrukturen bieten eine Reihe von Vorteilen:
- Sie vermeiden Datenredundanz.
- Die Verwaltung der Geodaten bleibt in den Fachbereichen.
- Daten haben eine höhere Aktualität und einen einheitlichen Stand.
- Software kann auf Basis der Standards entwickelt werden; Softwarekomponenten einer GDI lassen sich leichter austauschen.
- Datenkonsumenten können Geodaten beliebig kombinieren und überlagern.
Das Open Geospatial Consortium (OGC), eine internationale Organisation aus Vertretern von Industrie, Forschungs- und Regierungsorganisationen, hat eine Reihe von Diensten spezifiziert. Zu den vom UMN-Mapserver unterstützten zählen der Web Map Service (WMS), der Web Feature Service (WFS) und der Web Coverage Service (WCS).
In der Regel gibt der Web Map Service Kartenansichten in Form von Grafiken zurück. Zusätzlich lassen sich Sachdaten zu einem Kartenpunkt abrufen. Im Gegensatz dazu liefert ein Web Feature Service Vektordaten, die im XML-Dialekt Geography Markup Language (GML) kodiert sind. WFS-Clients bieten in der Regel mehr Funktionen und eine „lebendigere“ Darstellung als WMS-Clients. Der Web Coverage Service erlaubt den Zugriff auf Rohdaten – vor allem Rasterdaten –, die sich im Client analysieren, modellieren und darstellen lassen.
Dienstzugriff per Mapfile
Grundlage jeglicher Konfiguration mit dem UMN-Mapserver ist das Mapfile. Geodatendienste lassen sich ĂĽber das Common Gateway Interface Programm des UMN-Mapservers abfragen; die URL www.fqnserver.de/cgi-bin/mapserv?map=/map/grundlagen.map&service=WMS&request=getCapabilities&version=1.1.1 etwa ruft Daten eines WMS ab. Der Parameter map teilt dem CGI-Programm das gewĂĽnschte Mapfile mit. Die ĂĽbrigen Argumente sind vom OGC fĂĽr den jeweiligen Dienst spezifiziert; service gibt den gewĂĽnschten Dienst an, in diesem Fall WMS.
Es ist möglich, über ein Mapfile mehrere Geodatendienste anzubieten. Listing 1 zeigt die Konfiguration eines WMS und eines WFS in einem Mapfile. Die meisten der für Geodatendienste relevanten Einträge haben ein Präfix, das den Dienst identifiziert, etwa wfs_ oder wms_. Die Werte von Konfigurationsparametern wie wfs_title und wms_title können sich wiederholen. In neueren Versionen des UMN-Mapservers lässt sich mit dem Präfix ows_ ein Parameter für beide Dienste setzen: ows_title gibt den Titel sowohl für WMS als auch für WFS an.
Allerdings besitzt die Zugriffsmethode ĂĽber CGI zwei Nachteile: Erstens lassen sich Anfragen und Antworten nicht mit eigener Programmlogik modifizieren. Zweitens sind die Inhalte der Mapfiles hochgradig redundant. Das macht sich vor allem in komplexeren Geodateninfrastrukturen unangenehm bemerkbar.
Redundanz erhöht den Konfigurations- und Wartungsaufwand. Wechselt etwa ein Server den Namen, muss der Administrator in allen betroffenen Mapfiles die Parameter wms_onlineresource und wfs_onlineresource ändern. Auch die Kontaktangaben, etwa wms_address oder wms_contactperson, muss man bei Veränderungen händisch anpassen. Metadaten zu Geodaten werden oft als eigene zentrale Dienste angeboten. Das führt dazu, dass sie doppelt vorkommen: einmal im Mapfile und einmal als spezialisierter Metadatendienst. Obendrein wächst bei der CGI-Methode der Verwaltungsaufwand mit der Zahl der HTML-Templates, die man zum Beispiel für getFeatureInfo-Anfragen benötigt.
Bestimmte Geodatendienste sollen nur authentifizierten Nutzern zur Verfügung stehen, oft in unterschiedlichen, von der Nutzerkennung abhängigen Ansichten. Verwendet man das CGI-Interface, lässt sich ein anmeldungspflichtiger Geodatendienst jedoch nur mit einem zusätzlichen Authentifizierungsserver verwirklichen.
Hinzu kommt die Frage der Autorisierung, die eng mit dem angebotenen Dienst verknüpft ist. Ein räumlich oder inhaltlich eingeschränkter Zugriff zum Beispiel – auf Karten eines begrenzten Gebiets oder auf bestimmte Objekte –, ist ohne Eingriffe in die Logik des Geodatendienstes nur schwer zu realisieren. Dasselbe gilt für ein gezieltes Logging der Zugriffe.
Vereinfachen und erweitern
Seit Version 4.9 des UMN-Mapservers kann man mit der Mapscript-API in den Ablauf einer Serviceanfrage eingreifen. Dadurch lässt sich die Verwaltung von Geodatendiensten erheblich vereinfachen. Listing 2 zeigt, wie der Mechanismus funktioniert. Der Konstruktor ms_newMapObj() erzeugt ein neues Map-Objekt, das mit dem angegebenen Mapfile verknüpft ist. Mit den Funktionen der Mapscript-API lassen sich die im Mapfile konfigurierten Parameter ergänzen oder ändern; moveLayerUp() etwa ändert die Reihenfolge der Layer. Das modifizierte Map-Objekt dient anschließend als Grundlage für die Antwort des Geodatendienstes. owsdispatch() schließlich stellt das Resultat im gewünschten Format bereit.
Dadurch lässt sich ein zentrales Steuerungsskript für alle Geodatendienste entwickeln, das die genannten Nachteile vermeidet. Listing 3 zeigt schematisch den Programmablauf bei einer getCapabilities-Anfrage für einen Web Map Service. An zentraler Stelle setzt das Skript die URL für die wms_onlineresource für alle WMS-Dienste des Anbieters. Clients nutzen sie, um den Web Map Service einzubinden. Die XML-kodierte Antwort gibt Aufschlüsse über die Ressourcen des Dienstes: Kartenlayer, Abfragemöglichkeiten, räumliche Abdeckung, unterstützte Bildformate sowie Kontaktdaten des Dienstanbieters.
Informationen zu einem Punkt der Karte lassen sich mit der Mapscript-API ins HTML-Format wandeln. Es ist daher nicht mehr nötig, für den getFeatureInfo-Request den Template-Mechanismus des Mapservers zu bemühen (Listing 4).
Wie man den Anzeigeumfang für einen bestimmten Nutzer modifizieren kann, demonstriert Listing 5. Der Filter beschränkt die Ansicht auf bestimmte Objekte, in diesem Fall Gewässer, deren Attribut art den Wert 1024 hat.
Zwar beziehen sich alle Beispiele auf einen Web Map Service. Sie lassen sich jedoch in ähnlicher Form auf die anderen vom Mapserver unterstützten Geodatendienste anwenden.
Fazit
Mit der Mapscript-API des UMN-Mapservers lassen sich die Nachteile vermeiden, die bei einer dateibasierten Konfiguration von Geodatendiensten auftreten. Teile der Konfiguration, die sich bei mehreren Diensten wiederholen – etwa Kontaktdaten oder Servernamen – kann der Administrator zentral verwalten, zum Beispiel in einer Datenbank. Dienstspezifische Angaben wie die Visualisierungsanweisungen lassen sich im Mapfile konfigurieren. Außerdem kann man Geodatendienste mit zusätzlichen Funktionen anreichern und domainspezifische Lösungen für Autorisierung und Logging eng an die Logik des Geodatendienstes koppeln.
Jens Schumacher
plant die OGC Web Service Infrastruktur mit Open-Source-Software für das Landesamt für Geologie, Bergbau und Rohstoffe im Regierungspräsidium Freiburg.
Literatur
[1] Christian Wilk; Open-Source-GIS; Auf dem Präsentierteller; Geodaten mit dem UMN-Mapserver anbieten; iX 9/2006, S. 136
Listing 1: Konfiguration eines WMS und WFS in einem Mapfile
MAP
...
WEB
IMAGEPATH "/data/web/tmp/"
IMAGEURL "/tmp/"
METADATA
"wms_title" "Grundlagenkarte"
"wms_srs" "epsg:31467 epsg:4326 epsg:25832"
"wms_onlineresource" "http://www.fqnserver.de/cgi-bin/mapserv?map=/map/grundlagen.map&"
"wms_stateorprovince" "BY"
...
"wfs_title" "Grundlagenkarte"
"wfs_srs" "epsg:31467 epsg:4326 epsg:25832"
"wfs_onlineresource" "http://www.fqnserver.de/cgi-bin/mapserv?map=/map/grundlagen.map&"
"wfs_stateorprovince" "BY"
"ows_schemas_location" "http://schemas.opengeospatial.net/"
...
END
LAYER
NAME "gewaesser"
TYPE "polygon"
DUMP TRUE
METADATA
"wms_title" "Gewässer"
"wms_srs" "epsg:31467 epsg:4326 epsg:25832"
...
"wfs_title" "Gewässer"
"wfs_srs" "epsg:31467 epsg:4326 epsg:25832"
"gml_featureid" "ID"
"gml_include_items" "all"
END
...
END
Listing 2: OGC Web Service Dispatcher
<?php
...
$oMap = ms_newMapObj($themen[$_REQUEST["service_name"]]);
if (strtoupper($_REQUEST["request"]) == "GETFEATUREINFO" &&
strtoupper($_REQUEST["service"]) == "WMS") {
echo displayWMSFeatureInfoAsHTML($oMap,$_REQUEST);
exit(0);
}
?>
Listing 3: Zentrale Steuerung der Dienste
<?php
...
if (!extension_loaded("MapScript")) {
dl("php_mapscript.so");
}
$themen["grundlagenkarte"]="/map/grundlagen.map";
$themen["fachdatenkarte"]="/map/fachdatenkarte.map";
$oMap = ms_newMapObj($themen[$_REQUEST["service_name"]]);
if (strtoupper($_REQUEST["request"]) == "GETCAPABILITIES" &&
strtoupper($_REQUEST["service"]) == "WMS") {
$online_resource="http://".SERVER."/ows.phtml?service_name=".$_REQUEST["service_name"]."&";
$oMap->setmetadata("wms_onlineresource", $online_resource);
$oMap->setmetadata("wms_abstract", insertWSMetadata("http://meta.geospatialdata.de?id=34", "WMS"));
$map->setmetadata("wms_stateorprovince", iconv("ISO-8859-1", "UTF-8", "ThĂĽringen"));
}
$oMap->owsdispatch($request);
...
?>
Listing 4: Abfrage von Punktinformationen
<?php
...
$oMap = ms_newMapObj("/map/grundlagen.map");
$oMap->moveLayerUp(2);
ms_ioinstallstdouttobuffer();
$oMap->owsdispatch($request);
$contenttype = ms_iostripstdoutbuffercontenttype();
header('Content-type: '.$contenttype);
ms_iogetStdoutBufferBytes();
ms_ioresethandlers();
?>
Listing 5: Filterung der Kartenansicht
<?php
...
$oMap = ms_newMapObj($themen[$_REQUEST["service_name"]]);
$gewaesser = $oMap->getLayerByName("gewaesser");
if ($user.has_role("art_1024")) {
$gewaesser->setFilter(" art = '1024'");
}
$oMap->owsdispatch($request);
...
?>
(mr)