WMS-Services unterstützen eine Reihe von Operationen, z. B. GetCapabilities, GetMap, GetStyles usw., sodass Clientanwendungen den Service verwenden können, indem sie Parameter an die URL des Service anhängen. Die GetFeatureInfo-Operation wird auf die gleiche Weise verwendet. Sie ist für die Rückgabe der Attribute von Features konzipiert, die in einer Karte in verschiedenen Formaten wie z. B. HTML, XML und Nur-Text abgefragt werden.
Das folgende Beispiel zeigt eine GetFeatureInfo-Anforderung zusammen mit der Antwort im standardmäßigen HTML-Format:
Anforderung
http://gisserver.domain.com/arcgis/services/ihs_petroleum/MapServer/WMSServer?&service=WMS&version=1.1.0&request=GetFeatureInfo&layers=fields&query_layers=fields&styles=&bbox=47.130647,8.931116,48.604188,29.54223&srs=EPSG:4326&feature_count=10&x=562&y=193&height=445&width=1073&info_format=text/html&
Antwort
In vielen Fällen sind die Standardformate HTML, XML oder Nur-Text für die Antwort geeignet; es kann jedoch vorkommen, dass Sie das Format oder Schema der Antwort für die Ausführung einer bestimmten Geschäftslogik anpassen möchten. Beispielsweise könnten Sie die Feature-Informationen aus Gründen der Interoperabilität in einem Standardschema wie GML oder GeoJSON benötigen.
XSLT-Vorlagen
Mithilfe von XSLT-Vorlagen (Extensible Stylesheet Language Transformation) können Sie lesbare Ausgaben aus einer WMS GetFeatureInfo-Antwort erzeugen. Wenn Sie z. B. eine WMS GetFeatureInfo-Anforderung an den Server senden, antwortet der Server mit den angeforderten Features im XML-Format. Anschließend übernimmt die XSLT-Vorlage die "Übersetzung" des XML-Formats in ein angegebenes Format, z. B. HTML oder Nur-Text, sodass die endgültige Antwort gelesen werden kann.
Machen Sie sich mit der WMS GetFeatureInfo XML-Antwort und den standardmäßigen XSLT-Vorlagen vertraut, die im Lieferumfang der ArcGIS for Server-Installation enthalten sind, da die Anpassung der GetFeatureInfo-Antwort dadurch erleichtert wird. In den nächsten Abschnitten werden die einzelnen Optionen detailliert erläutert.
XML-Antwort für GetFeatureInfo
Das nachfolgende Beispiel zeigt eine XML-Antwort für "GetFeatureInfo" in einem WMS-Service:
<?xml version="1.0" encoding="UTF-8"?>
<esri_wms:FeatureInfoResponse version="1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
<esri_wms:FeatureInfoCollection layername="fields">
<esri_wms:FeatureInfo>
<esri_wms:Field>
<esri_wms:FieldName><![CDATA[OBJECTID]]></esri_wms:FieldName>
<esri_wms:FieldValue><![CDATA[1]]></esri_wms:FieldValue>
</esri_wms:Field>
<esri_wms:Field>
<esri_wms:FieldName><![CDATA[Shape]]></esri_wms:FieldName>
<esri_wms:FieldValue><![CDATA[Polygon]]></esri_wms:FieldValue>
</esri_wms:Field>
<esri_wms:Field>
<esri_wms:FieldName><![CDATA[Shape_Area]]></esri_wms:FieldName>
<esri_wms:FieldValue><![CDATA[0.009079]]></esri_wms:FieldValue>
</esri_wms:Field>
...
<!-- there could be more <esri_wms:Field> -->
...
<esri_wms:Field>
<esri_wms:FieldGeometry>
<esri_wms:Point><![CDATA[0,0]]></esri_wms:Point>
<esri_wms:Multipoint>
<esri_wms:Point><![CDATA[0,45]]></esri_wms:Point>
<esri_wms:Point><![CDATA[10,55]]></esri_wms:Point>
<!-- there could be more <esri_wms:Point> -->
</esri_wms:Multipoint>
<esri_wms:Polyline>
<esri_wms:Path>
<esri_wms:Point><![CDATA[0,45]]></esri_wms:Point>
<esri_wms:Point><![CDATA[10,55]]></esri_wms:Point>
<!-- there could be more <esri_wms:Point> -->
</esri_wms:Path>
<!-- there could be more <esri_wms:Path> -->
</esri_wms:Polyline>
<esri_wms:Polygon>
<esri_wms:Ring>
<esri_wms:Point><![CDATA[0,45]]></esri_wms:Point>
<esri_wms:Point><![CDATA[10,55]]></esri_wms:Point>
<esri_wms:Point><![CDATA[15,25]]></esri_wms:Point>
<!-- there could be more <esri_wms:Point> -->
</esri_wms:Ring>
<!-- there could be more <esri_wms:Ring> -->
</esri_wms:Polygon>
</esri_wms:FieldGeometry>
</esri_wms:Field>
</esri_wms:FeatureInfo>
...
<!-- there could be more <esri_wms:FeatureInfo> -->
...
</esri_wms:FeatureInfoCollection>
...
<!-- there could be more <esri_wms:FeatureInfoCollection> -->
...
</esri_wms:FeatureInfoResponse>
Achten Sie auf die folgenden Details:
- Das Stammtag <FeatureInfoResponse> kann mehrere <FeatureInfoCollection>-Elemente enthalten.
- Jedes <FeatureInfoCollection>-Element enthält die Attributfelder und Werte aller identifizierten Features aus einem einzelnen WMS-Layer.
- Die Informationen für ein einzelnes identifiziertes Feature sind in einem <FeatureInfo>-Tag enthalten. Achten Sie auf das Namen-/Wertepaar für jedes Feld.
- Jedes <FeatureInfo>-Tag enthält Raumbezugsinformation.
- Sofern verfügbar, wird die Feature-Geometrie in einem <FieldGeometry>-Tag zurückgegeben.
- Eine Feldgeometrie kann eine Punkt-, Multipoint-, Polylinien- oder Polygon-Geometrie enthalten.
Standardmäßige XSLT-Vorlagen
Im Lieferumfang von ArcGIS for Server sind XSLT-Vorlagen für die unterstützten Formate enthalten, die in den WMS-Funktionsdateien aufgelistet sind. Wenn Sie beispielsweise das Verzeichnis für diese Vorlagen unter <ArcGIS Server-Installationsverzeichnis>\Styles\WMS öffnen, wird Folgendes angezeigt:
- featureinfo_application_geojson.xsl
- featureinfo_application_vnd.esri.wms_featureinfo_xml.xsl
- featureinfo_application_vnd.ogc.wms_xml.xsl
- featureinfo_text_html.xsl
- featureinfo_text_plain.xsl
- featureinfo_text_xml.xsl
Wie die Namen implizieren, wird jede Vorlage verwendet, um eine Standardantwort für GetFeatureInfo in einem lesbaren Format wie GeoJSON, Nur-Text und XML zu erzeugen.
Die HTML-Beispieltabelle mit dem blauen Titel, die am Anfang dieses Themas erwähnt wird, wurde mit der standardmäßigen XSLT-HTML-Vorlage erzeugt. Wenn Sie die XML-Daten im Rohformat abrufen möchten, können Sie alternativ den GetFeatureInfo-Anforderungsparameter "INFO_FORMAT" auf "application/vnd.esri.wms_raw_xml" festlegen. Mit dieser Methode können Sie Ihre eigene XSLT-Vorlage erstellen.
Anpassen der Antwort für GetFeatureInfo
Nachdem Sie sich mit den XML- und XSLT-Vorlagen für die GetFeatureInfo-Antwort vertraut gemacht haben, können Sie verschiedene Methoden zum Anpassen der WMS GetFeatureInfo-Antwort untersuchen.
Ändern der standardmäßigen XSLT-Vorlagen
Eine Methode besteht in der physischen Änderung der XSLT-Vorlagen. Wenn Sie z. B. die HTML-Vorlage "featureinfo_text_html.xsl" in einem Texteditor öffnen und das <Style>-Tag durch folgende XML-Daten ersetzen, wird die Farbe des Tabellentitels in Rot geändert:
Beispiel-XML
<style type="text/css">
table, th, td {
border:1px solid #e5e5e5;
border-collapse:collapse;
font-family: arial; font-size: 80%;
color: #333333 } th, td {
valign: top;
text-align: center;
} th {
background-color: #ffb7b7 }
caption {
border:1px solid #e5e5e5;
border-collapse:collapse;
font-family: arial; font-weight: bold;
font-size: 80%; text-align: left;
color: #333333; }
</style>
Beispielantwort
Wenn Sie diese Vorlagen jedoch ändern, hat das direkte Auswirkungen auf alle WMS-Services, die über ArcGIS for Server veröffentlicht werden. Vermeiden Sie deshalb die Verwendung von Logik in den Vorlagen, die spezifisch für Karten-Services ist.
Verwenden des Parameters "xsl_template"
Eine andere Möglichkeit, die GetFeatureInfo-Antwort anzupassen, besteht darin, das Verhalten der standardmäßigen XSLT-Vorlagen mit dem Parameter "xsl_template" zu überschreiben. "xsl_template" ist ein spezifischer Parameter von Esri, den Sie in der URL einer XSLT-Vorlagendatei festlegen können. Wenn die Vorlage in der URL-Zeichenfolge angegeben wird, wird die Standardvorlage vom WMS-Service überschrieben, und die angegebene Vorlage wird verwendet. Wenn Sie bereits eine benutzerdefinierte Vorlage erstellt haben, ist diese Methode am besten geeignet, um die Vorlage in der GetFeatureInfo-Antwort zu nutzen.
Hinweis:
Wenn Sie den Parameter "xsl_template" verwenden, muss die XSLT-Vorlage nicht der Bennenungskonvention folgen, die für Standardvorlagen gilt, sie muss jedoch über eine URL verfügbar sein. Bei Angabe eines lokalen Pfades oder eines UNC-Pfades schlägt die Anforderung fehl.
Das nachfolgende Beispiel zeigt eine GetFeatureInfo-Anforderung mit dem Parameter "xsl_template":
http://gisserver.domain.com/arcgis/services/ihs_petroleum/MapServer/WMSServer?&service=WMS&version=1.1.1&request=GetFeatureInfo&layers=pipelines&query_layers=pipelines&styles=&bbox=47.119661,28.931116,48.593202,29.54223&srs=EPSG:4326&feature_count=10&x=389&y=120&height=445&width=1073&info_format=text/plain&xsl_template=http://server/resources/xsl/featureinfo_application_geojson.xsl
Die oben genannte URL verweist auf eine externe Vorlage, die die Standardvorlage überschreibt. Das XML für die angepasste Vorlage lautet wie folgt:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
<xsl:output method="text" indent="yes" encoding="ISO-8859-1"/>
<xsl:template match="/">
{
"type": "FeatureCollection", "spatialReference": { "wkid": <xsl:value-of select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection/esri_wms:FeatureInfo/esri_wms:CRS"/> }, "features": [<xsl:for-each select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection/esri_wms:FeatureInfo">
{
"type": "Feature", <xsl:if test="count(esri_wms:Field/esri_wms:FieldGeometry/*) > 0">
"geometry": {
<xsl:for-each select="esri_wms:Field/esri_wms:FieldGeometry">
<xsl:for-each select="esri_wms:Point">"type": "Point", "coordinates": [<xsl:value-of select="."/>]</xsl:for-each>
<xsl:for-each select="esri_wms:Multipoint">"type": "MultiPoint", "coordinates": [<xsl:for-each select="esri_wms:Point">[<xsl:value-of select="."/>]<xsl:if test = "position() != last()">,</xsl:if></xsl:for-each>]</xsl:for-each>
<xsl:for-each select="esri_wms:Polyline">"type": "MultiLineString", "coordinates": [<xsl:for-each select="esri_wms:Path"> [<xsl:for-each select="esri_wms:Point">[<xsl:value-of select="."/>]<xsl:if test = "position() != last()">,</xsl:if></xsl:for-each>]<xsl:if test = "position() != last()">,</xsl:if></xsl:for-each>]</xsl:for-each>
<xsl:for-each select="esri_wms:Polygon">"type": "Polygon", "coordinates": [<xsl:for-each select="esri_wms:Ring"> [<xsl:for-each select="esri_wms:Point">[<xsl:value-of select="."/>]<xsl:if test = "position() != last()">,</xsl:if></xsl:for-each>]<xsl:if test = "position() != last()">,</xsl:if></xsl:for-each>]</xsl:for-each>
</xsl:for-each>
}, </xsl:if>
"properties": {<xsl:for-each select="esri_wms:Field">
"<xsl:value-of select="esri_wms:FieldName"/>": "<xsl:value-of select="esri_wms:FieldValue"/>"<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
}, "layerName": "<xsl:value-of select="../@layername"/>" }<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
] }
</xsl:template>
</xsl:stylesheet>
Die Vorlage wurde erstellt, damit der WMS-Service die GetFeatureInfo-Antworten in Nur-Text-GeoJSON mit Feature-Geometrie statt im standardmäßigen HTML-Format zurückgibt. GeoJSON kann von vielen JavaScript-Bibliotheken analysiert werden, sodass Ihre Antworten in einem einfach lesbaren Format in Webseiten integriert werden können.
Das nachfolgende Beispiel zeigt eine GetFeatureInfo-Antwort im GeoJSON-Format als Datenquelle für Ext.Grid in einer OpenLayers-Webkartenanwendung:
Um auf das vorhergehende Beispiel aufzubauen, kann die Vorlage im nächsten Beispiel verwendet werden, um ein Video-Objekt in der Antwort einzubetten:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
<!--
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
--> <xsl:output
method="html" indent="yes"
encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:template match="/"> <!--<html>
<head>-->
<style type="text/css">
table, th, td {
border:1px solid #e5e5e5;
border-collapse:collapse;
font-family: arial; font-size: 80%;
color: #333333 } th, td {
valign: top;
text-align: center;
} th {
background-color: #aed7ff;
}
caption {
border:1px solid #e5e5e5;
border-collapse:collapse;
font-family: arial; font-weight: bold;
font-size: 80%; text-align: left;
color: #333333;
background-color: #aed7ff; }
</style>
<!--</head>
<body>--> <div>
<xsl:for-each select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection"> <table width="100%" cellpadding="0" cellspacing="0" border="1">
<tbody> <caption>layer names: '<xsl:value-of select="@layername"/>'</caption>
<xsl:for-each select="esri_wms:FeatureInfo[1]/esri_wms:Field">
<xsl:variable name="fieldName" select="esri_wms:FieldName"/>
<xsl:variable name="fieldValue" select="esri_wms:FieldValue"/> <xsl:if test="$fieldName = 'PLOT_SYMBOL_GROUP'">
<xsl:choose>
<xsl:when test="$fieldValue = 2"> <tr>
<td>
wiki link </td>
<td>
<a target="_blank">
<xsl:attribute name="href">
http://en.wikipedia.org/wiki/Oil_well </xsl:attribute>
Oil Well </a> </td>
</tr> <tr>
<td>
video </td>
<td>
<div>
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/HVxsbb1lDsQ"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/HVxsbb1lDsQ" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>
</div>
</td>
</tr>
</xsl:when> </xsl:choose>
</xsl:if> </xsl:for-each>
</tbody>
</table> </xsl:for-each>
</div>
<!--</body>
</html>-->
</xsl:template>
Das nachfolgende Beispiel zeigt die GetFeatureInfo-Antwort mit einem eingebetteten Video in einer OpenLayers-Webkartenanwendung:
Im Folgenden wird ein eingehendes Beispiel gezeigt, in dem die GetFeatureInfo-Antwort umfassend angepasst wird und ein JavaScript-Codeausschnitt eingebettet wird. Mit dem Code wird eine Tour in der Plug-In-Webanwendung für Google Earth abgespielt. Beachten Sie, dass in dieser XSLT-Vorlage eine Logik enthalten ist, die spezifisch für einen bestimmten WMS-Service ist. Aus diesem Grund sollte immer der Parameter "xsl_template" verwendet werden, um auf diese Vorlage zu verweisen. Sie sollte nicht als Standardvorlage eingerichtet werden.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
<!--
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
--> <xsl:output
method="html" indent="yes"
encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:template match="/"> <!--<html>
<head>-->
<style type="text/css">
table, th, td {
border:1px solid #e5e5e5;
border-collapse:collapse;
font-family: arial; font-size: 80%;
color: #333333 } th, td {
valign: top;
text-align: center;
} th {
background-color: #aed7ff;
}
caption {
border:1px solid #e5e5e5;
border-collapse:collapse;
font-family: arial; font-weight: bold;
font-size: 80%; text-align: left;
color: #333333;
background-color: #aed7ff; }
</style>
<!--</head>
<body>--> <div>
<xsl:for-each select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection"> <table width="100%" cellpadding="0" cellspacing="0" border="1">
<tbody> <caption>layer names: '<xsl:value-of select="@layername"/>'</caption>
<xsl:for-each select="esri_wms:FeatureInfo[1]/esri_wms:Field">
<xsl:variable name="fieldName" select="esri_wms:FieldName"/>
<xsl:variable name="fieldValue" select="esri_wms:FieldValue"/> <xsl:if test="$fieldName = 'WGS84_LONGITUDE'">
<xsl:variable name="lon" select="esri_wms:FieldValue"/>
<tr>
<td>lon</td>
<td><xsl:value-of select="$lon"/></td>
<script type="text/javascript">
popup_lon = '<xsl:value-of select="$lon"/>';
</script>
</tr>
</xsl:if>
<xsl:if test="$fieldName = 'WGS84_LATITUDE'">
<xsl:variable name="lat" select="esri_wms:FieldValue"/>
<tr>
<td>lat</td>
<td><xsl:value-of select="$lat"/></td>
<script type="text/javascript">
popup_lat = '<xsl:value-of select="$lat"/>';
</script>
</tr>
</xsl:if> <xsl:if test="$fieldName = 'PLOT_SYMBOL_GROUP'">
<xsl:choose> <xsl:when test="$fieldValue = 14">
<tr>
<td>
3d map </td>
<td>
<div id="map3d" style="width:384px;height:256px;"></div>
<script type="text/javascript">
google.earth.createInstance( 'map3d', function(instance) {
ge = instance;
ge.getWindow().setVisibility(true);
var kmlStr = ''
+ '<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">' + '<gx:Tour>' + '<gx:Playlist><gx:FlyTo>' + '<gx:duration>20.0</gx:duration>' + '<LookAt>' + '<longitude>' + popup_lon + '</longitude>' + '<latitude>' + popup_lat + '</latitude>' + '<altitude>0</altitude>' + '<heading>0</heading>' + '<tilt>0</tilt>' + '<range>500</range>' + '<altitudeMode>relativeToGround</altitudeMode>' + '</LookAt>' + '</gx:FlyTo></gx:Playlist>' + '</gx:Tour>' + '</kml>';
var kmlObj = ge.parseKml(kmlStr);
ge.getTourPlayer().setTour(kmlObj);
ge.getTourPlayer().play(); },
function() {
}
);
</script>
</td>
</tr>
</xsl:when> </xsl:choose>
</xsl:if> </xsl:for-each>
</tbody>
</table> </xsl:for-each>
</div>
<!--</body>
</html>-->
</xsl:template>