"Seegrid will be due for a migration to confluence on the 1st of August. Any update on or after the 1st of August will NOT be migrated"

Deegree GeoSciML v2.0 Implementation

Also see DeegreeGeoSciMLImplementationDiscussion

Introduction

This page documents the implementation of a GeoSciML Web Feature Service using the Lat/Lon Deegree Web Feature Server application. The content is based on experience gained by GeoScience Victoria using Deegree to implement Web Feature Services for GeoSciML TestBed3 (link) and the Australian Earth Resource Mark-up Language for the AuScope project.

Users with a sound understanding of relational database management systems, XML schema for GML and XSLT should be able to adapt this work to serve GeoSciML from their databases.

Inherent limitations of Deegree (see Appendix One) mean the user cannot map a database directly to a GML application schema such as GeoSciML. Deegree can, however, allow the user to configure complex GML 3.1 feature types that are very close to a particular application schema in structure and content. These 'interim feature types' can then be transformed into a feature type from an appropriate application schema using the Deegree Virtual Output Formats (an inbuilt XSLT engine). Conversely Virtual Output Formats allow requests made for feature types in the application schema to be translated into requests against the interim schema.

Background Reading

This page assumes that the reader has read the Deegree WFS Manual (v2.1 or v2.2). In addition we recommend that the reader is familiar with the GSC (Geological Survey of Canada) GIN Mediator approach. While the implementation may differ, the principles are the same and this work has benefited greatly from the experience and support of the GSC developers.

Design Requirements

The Deegree solution is intended to meet the following requirements:
  • Serve feature types from GML application schemas such as GeoSciML; and
  • Respond to valid requests for these feature types.

The following are not supported by this work:
  • GeoSciML Profiles.

Preliminary Installation

Tomcat

Requirements

Web http://tomcat.apache.org
Version 5.5.x plus (see the Deegree wiki for information about versions known to cause problems with long HTTP POST requests)
Java JRE or JDK 1.5.x plus

Setup

Tomcat installation and management varies between platforms, consult your System Administrator for guidance or consult the Tomcat set-up documentation.

Deegree

Requirements

Web http://www.deegree.org
Version 2.3 (stable version.) Known limitations mean users should not use earlier versions of deegree (eg 2.2 and 2.1).
Tomcat See above

Setup

Deegree installation is documented in section 2 of the Deegree WFS Documentation. The Deegree web archive (.war file) can be deployed by:
  • Placing the deegree-wfs.war file in the $TOMCAT_HOME$/webapps directory; or
  • Using the WAR file to deploy tool in the Tomcat Manager (typically located at http://[hostname]:8080/manager/html)
  • Once installed the service URL will be: http://[hostname]:8080/deegree-wfs/services
  • Should you wish to rename the service, for example to enable multiple instances of Deegree to be deployed in the same Tomcat instance, then rename the .war file before deploying it. For example, GeoSciML.war would have the URL http://[hostname]:8080/GeoSciML/services

Database

Requirements

Supported Data Sources Typically require the appropriate JDBC drivers. See Section 5 of the Deegree WFS Documentation for details.
  PostGIS
  Oracle
  Generic SQL (eg Microsoft SQL Server or IBM DB2)
  Shapefile
  ArcSDE

Setup

  • Database must reside at a location accessible by Deegree.
  • The database user used by Deegree must have sufficient privileges to query the database.
  • The database user used for database configuration must have sufficient privileges to create database views and, potentially, tables and spatial or aspatial indexes.

Sample Implementation

A sample configuration (gsml:MappedFeature specified with a very simple gsml:GeologicUnit) has been attached for test and reference purposes. All examples used below are derived from this sample implementation.

To install this implementation replace the [deegree install path]/WEB-INF/conf/wfs directory with the version of wfs included in the attached zip file and restart/reload Deegree in Tomcat.

NOTE: this will require an appropriately configured database - a sample PostGIS database will be posted on this site as soon as possible..

Architecture

This approach uses the same architecture as the GIN Mediator, the difference being that the request mapping and response handler are implemented using Deegree's own XSLT-based 'Virtual Output Formats' (In Filter and Out Filter respectively).

DeegreeArchitecture.png

The client sends a valid GeoSciML request to the service. The request is then transformed into a request against the interim Deegree schema by the inFilter XSL transform and executed by Deegree. The subsequent response is then transformed into GeoSciML by the outFilter XSL transformation. Simple!

Example

Consider this simple instance of a GeoSciML MappedFeature:
<gsml:MappedFeature gml:id="gsml.mappedfeature.158725">
   <gsml:observationMethod>
      <gsml:CGI_TermValue>
         <gsml:value codeSpace="http://urn.opengis.net">urn:ogc:def:nil:OGC::missing</gsml:value>
      </gsml:CGI_TermValue>
   </gsml:observationMethod>
   <gsml:positionalAccuracy>
      <gsml:CGI_TermValue>
         <gsml:value codeSpace="http://urn.opengis.net">urn:ogc:def:nil:OGC:missing</gsml:value>
      </gsml:CGI_TermValue>
   </gsml:positionalAccuracy>
   <gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
   <gsml:specification>
      <gsml:GeologicUnit gml:id="gsml.geologicunit.16777549126932931">
         <gml:name codeSpace="urn:cgi:party:CGI:GSV">Castlemaine Group - Bendigonian (Ocb)</gml:name>
         <gml:name codeSpace="http://www.gsv-tb.dpi.vic.gov.au/GeoSciMLv2.0/GeologicUnit/wfs">urn:cgi:feature:GSV:GeologicalFeatureID:16777549126932931</gml:name>
         <gsml:observationMethod>
            <gsml:CGI_TermValue>
               <gsml:value codeSpace="http://urn.opengis.net">urn:ogc:def:nil:OGC::missing</gsml:value>
            </gsml:CGI_TermValue>
         </gsml:observationMethod>
         <gsml:purpose>typicalNorm</gsml:purpose>
         <gsml:geologicUnitType xlink:href="urn:cgi:classifier:CGI:GeologicUnitType:2008:biostratigraphic_unit"/>
      </gsml:GeologicUnit>
   </gsml:specification>
   <gsml:shape>
      <gml:MultiSurface srsName="EPSG:4326">
         <gml:surfaceMember>
            <gml:Polygon srsName="EPSG:4326">
               <gml:exterior>
                  <gml:LinearRing>
                     <gml:posList srsDimension="2">144.44470087499968 -36.92760058333364 144.4427465666664 -36.928551525000294 144.442524783333 -36.92884335000028 144.4423674499997 -36.926858533333615 144.44122311666627 -36.91967264166702 144.44226951666636 -36.92210885000031 144.44470087499968 -36.92760058333364</gml:posList>
                  </gml:LinearRing>
               </gml:exterior>
            </gml:Polygon>
         </gml:surfaceMember>
      </gml:MultiSurface>
   </gsml:shape>
</gsml:MappedFeature>

The closest implementation (interim schema) Deegree can produce is:
<gsml:MappedFeature gml:id="gsml.mappedfeature.158725">
   <gsml:observationMethod>
      <gsml:ObservationMethod gml:id="obs.meth.158725">
         <gsml:value>urn:ogc:def:nil:OGC::missing</gsml:value>
         <gsml:value_codeSpace>http://urn.opengis.net</gsml:value_codeSpace>
      </gsml:ObservationMethod>
   </gsml:observationMethod>
   <gsml:positionalAccuracy>urn:ogc:def:nil:OGC:missing</gsml:positionalAccuracy>
   <gsml:positionalAccuracy_codeSpace>http://urn.opengis.net</gsml:positionalAccuracy_codeSpace>
   <gsml:samplingFrame>urn:cgi:feature:CGI:EarthNaturalSurface</gsml:samplingFrame>
   <gsml:specification>
      <gsml:GeologicUnit gml:id="gsml.geologicunit.16777549126932931">
         <gsml:observationMethod>urn:ogc:def:nil:OGC::missing</gsml:observationMethod>
         <gsml:observationMethod_codeSpace>http://urn.opengis.net</gsml:observationMethod_codeSpace>
         <gsml:purpose>typicalNorm</gsml:purpose>
         <gsml:name>
            <gsml:GML_Name gml:id="gml.name.16777549126932927.16777549126932931">
               <gsml:name>Castlemaine Group - Bendigonian (Ocb)</gsml:name>
               <gsml:name_codeSpace>urn:cgi:party:CGI:GSV</gsml:name_codeSpace>
            </gsml:GML_Name>
         </gsml:name>
         <gsml:name>
            <gsml:GML_Name gml:id="gml.name.16777549126932931">
               <gsml:name>urn:cgi:feature:GSV:GeologicalFeatureID:16777549126932931</gsml:name>
               <gsml:name_codeSpace>http://www.gsv-tb.dpi.vic.gov.au/GeoSciMLv2.0/GeologicUnit/wfs</gsml:name_codeSpace>
            </gsml:GML_Name>
         </gsml:name>
         <gsml:geologicUnitType>urn:cgi:classifier:CGI:GeologicUnitType:2008:biostratigraphic_unit</gsml:geologicUnitType>
      </gsml:GeologicUnit>
   </gsml:specification>
   <gsml:shape>
      <gml:MultiSurface srsName="EPSG:4326">
         <gml:surfaceMember>
            <gml:Polygon srsName="EPSG:4326">
               <gml:exterior>
                  <gml:LinearRing>
                     <gml:coordinates cs="," decimal="." ts=" ">144.44470087499968,-36.92760058333364 144.4427465666664,-36.928551525000294 144.442524783333,-36.92884335000028 144.4423674499997,-36.926858533333615 144.44122311666627,-36.91967264166702 144.44226951666636,-36.92210885000031 144.44470087499968,-36.92760058333364</gml:coordinates>
                  </gml:LinearRing>
               </gml:exterior>
            </gml:Polygon>
         </gml:surfaceMember>
      </gml:MultiSurface>
   </gsml:shape>
</gsml:MappedFeature>

Note that the gsml:specification/gsml:GeologicUnit/gml:name element is in the wrong namespace; the codeSpace and href attributes are not returned as attributes but elements and the CGI_TermValue complex DataType is a feature. To produce a valid gsml:MappedFeature the Deegree XSLT engine must:
  • Map gsml:specification/gsml:GeologicUnit/gsml:name to gsml:specification/gsml:GeologicUnit/gml:name and ~/gsml:name_codeSpace to ~/gml:name/@codeSpace;
  • Map gsml:samplingFrame to gsml:samplingFrame/@xlink:href;
  • Map gsml:specification/gsml:GeologicUnit/gsml:geologicUnitType to gsml:specification/gsml:GeologicUnit/gsml:geologicUnitType/@xlink:href; and
  • Cast the interim gsml:CGI_TermValue features to a valid gsml:CGI_TermValue DataTypes.
  • Convert gml:coordinates to gml:posList. (gml:coordinates has been deprecated in GML 3.1.1and should not be used. Deegree v2.1 returns gml:coordinates, v2.2 plus return gml:posList.)

Also, for the WFS to be a valid GeoSciML service, GetFeature requests must be made against GeoSciML feature types as defined in the schema. However, as the Deegree service, in reality, serves feature types from the interim schema, requests must be translated into requests against the interim feature type. Consequently the following request for a gsml:MappedFeature specified with a gsml:GeologicUnit with a particular name:
<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:gsml="urn:cgi:xmlns:CGI:GeoSciML:2.0" maxFeatures="10" service="WFS" version="1.1.0">
  <wfs:Query typeName="gsml:MappedFeature">
    <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
      <ogc:PropertyIsEqualTo>
        <ogc:PropertyName>gsml:specification/gsml:GeologicUnit/gml:name</ogc:PropertyName>
        <ogc:Literal>Castlemaine Group - Bendigonian (Ocb)</ogc:Literal>
      </ogc:PropertyIsEqualTo>
    </ogc:Filter>
  </wfs:Query>
</wfs:GetFeature>

Must become:
<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:gsml="urn:cgi:xmlns:CGI:GeoSciML:2.0" maxFeatures="10" service="WFS" version="1.1.0">
  <wfs:Query typeName="gsml:MappedFeature">
    <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
      <ogc:PropertyIsEqualTo>
        <ogc:PropertyName>gsml:specification/gsml:GeologicUnit/gsml:name/gsml:GML_Name/gsml:name</ogc:PropertyName>
        <ogc:Literal>Castlemaine Group - Bendigonian (Ocb)</ogc:Literal>
      </ogc:PropertyIsEqualTo>
    </ogc:Filter>
  </wfs:Query>
</wfs:GetFeature>

Note the changed ogc:PropertyName XPath which now matches the interim Deegree schema. This will need to be repeated for all properties where the interim schema does not match the target schema.

Configuration

Assumptions

The following configuration assumes that:
  • the user is familiar with the basics of GML/XML schema documents and their rules and requirements;
  • the user is familiar with the basics of Extensible Stylesheet Language Transformations (XSLT); and
  • the Deegree interim schema has been designed to be as close to GeoSciML as possible and that all database to GeoSciML mapping occurs in the database. Alternatives are discussed in Appendix Two.

Deegree (i): Interim Schema

Deegree uses annotated XML schema documents to configure feature types served by the WFS. The XSD is a valid GML 3.1.1 schema and is augmented with xsd:annotation/xsd:appinfo elements to provide Deegree with necessary database connection and mapping information.

Below is an initial fragment of the XSD used by Deegree to configure the feature type. A copy can be found in wfs/featuretypes/GeoSciMLv2.0.xsd in the attached sample configuration zip file. (For clarity Deegree annotation has been left out for this step.)

<xsd:schema xmlns:gml="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:deegreewfs="http://www.deegree.org/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gsml="urn:cgi:xmlns:CGI:GeoSciML:2.0" targetNamespace="urn:cgi:xmlns:CGI:GeoSciML:2.0" elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/feature.xsd"/>
   <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/geometryAggregates.xsd"/>
        <xsd:element name="MappedFeature" type="gsml:MappedFeatureType" substitutionGroup="gml:_Feature"/>
   <xsd:complexType name="MappedFeatureType">
      <xsd:complexContent>
         <xsd:extension base="gml:AbstractFeatureType">
            <xsd:sequence>
               <xsd:element name="observationMethod" type="gml:FeaturePropertyType"/>
               <xsd:element name="positionalAccuracy" type="xsd:string"/>
               <xsd:element name="positionalAccuracy_codeSpace" type="xsd:string"/>
               <xsd:element name="samplingFrame" type="xsd:string"/>
               <xsd:element name="specification" type="gml:FeaturePropertyType"/>
               <xsd:element name="shape" type="gml:GeometryPropertyType"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:element name="GeologicUnit" type="gsml:GeologicUnitType" substitutionGroup="gml:_Feature"/>
   <xsd:complexType name="GeologicUnitType">
      <xsd:complexContent>
         <xsd:extension base="gml:AbstractFeatureType">
            <xsd:sequence>
               <xsd:element name="observationMethod" type="xsd:string"/>
               <xsd:element name="observationMethod_codeSpace" type="xsd:string"/>
               <xsd:element name="purpose" type="xsd:string"/>
               <xsd:element name="name" type="gml:FeaturePropertyType" maxOccurs="unbounded"/>
               <xsd:element name="geologicUnitType" type="xsd:string"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:element name="GML_Name" type="gsml:GML_NameType" substitutionGroup="gml:_Feature"/>
   <xsd:complexType name="GML_NameType">
      <xsd:complexContent>
         <xsd:extension base="gml:AbstractFeatureType">
            <xsd:sequence>
               <xsd:element name="name" type="xsd:string"/>
               <xsd:element name="name_codeSpace" type="xsd:string"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:element name="ObservationMethod" type="gsml:CGI_TermValueType" substitutionGroup="gml:_Feature"/>
   <xsd:complexType name="CGI_TermValueType">
      <xsd:complexContent>
         <xsd:extension base="gml:AbstractFeatureType">
            <xsd:sequence>
               <xsd:element name="value" type="xsd:string"/>
               <xsd:element name="value_codeSpace" type="xsd:string"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
</xsd:schema>

Note the following important aspects about this schema:
  • All complex types are GML features. In same cases this correctly matches the target schema (gsml:MappedFeature and gsml:GeologicUnit) but in others it does not (gsml:GML_Name and gsml:ObservationMethod.)
  • gsml:GML_Name and gsml:ObservationMethod are actually relatively simple types, both mapping to gml:ScopedName, a string with a codeSpace attribute. Deegree cannot populate attributes on elements so the codeSpace is returned as an element suffixed, in this model, with _codeSpace. Because there is a transitive dependency between the value and the attribute, and they are multi-valued properties, they must be configured as features in the interim schema.
  • In some cases elements of type gml:ScopedName (eg gsml:MappedFeature/gsml:positionalAccuracy and gsml:GeologicUnit/gsml:observationMethod) are single valued and do not necessarily have to be placed in a complex type. In GSV's case this avoided getting Deegree to join the same view to itself to populate the element.
  • gsml:MappedFeature/gsml: samplingFrame and gsml:GeologicUnit/gsml:geologicUnitType will map to xlink:href attributes in GeoSciML. Again, we can't populate this attribute in Deegree.
  • gsml:MappedFeature/gsml:shape is populated by Deegree and the user has no control over the GML geometry type it chooses. As discussed above, Deegree v2.1 uses gml:coordinates and as this type has been deprecated in GML 3.1.1. It must be mapped to gml:posList. Deegree v2.2 onwards uses gml:posList.
  • xsd:complexTypes can be reused by multiple elements, for example gsml:CGI_TermValueType could be reused for multi-valued gsml:positionalAccuracy values.

Database

Deegree expects a one-to-one mapping between a schema element bound to a complexType and a source table or view in the underlying database. It is beyond the scope of of this document to describe how to write these views, as they will vary between databases, however we feel it is important to note the following:
  • If all data for elements are provided using views then Deegree ultimately ends up writing SQL queries joining views to views and, where appropriate for filtered GetFeature requests, writing WHERE clauses against them. This can take database indexes out of play and can be detrimental to performance.
  • GSV achieved significant improvements in performance by creating tables from the mapping views, indexing them approriately and then using them as the datasource for Deegree.
  • This approach does create overheads and (over?)headaches maintaining up-to-date data and accommodating changes to the mapping as or requirements schema evolve.

Deegree (ii): Database Mapping

Once the source views/tables are ready the feature type XSD can be annotated with the Deegree configuration information. (Line numbers that follow refer to line numbers in the reference sample-deegree-conf.zip -> wfs/featuretypes/GeoSciMLv2.0.xsd.)

Database Connection

The database connection parameters are specified at the beginning of the document (lines 7 to 21 of GeoSciMLv2.0.xsd) these will all be specific to your database implementation.
   <xsd:annotation>
      <xsd:appinfo>
         <deegreewfs:Prefix>gsml</deegreewfs:Prefix>
         <deegreewfs:Backend>POSTGIS</deegreewfs:Backend>
         <deegreewfs:DefaultSRS>EPSG:4326</deegreewfs:DefaultSRS>
         <JDBCConnection xmlns="http://www.deegree.org/jdbc">
            <Driver>org.postgresql.Driver</Driver>
            <Url>jdbc:postgresql://localhost:5432/gsmltestbed</Url>
            <User>gsmltb3</User>
            <Password>gsmltb3</Password>
            <SecurityConstraints/>
            <Encoding>utf-8</Encoding>
         </JDBCConnection>
         <deegreewfs:SuppressXLinkOutput>false</deegreewfs:SuppressXLinkOutput>
      </xsd:appinfo>
   </xsd:annotation>

NOTE: To ensure you always produce valid GeoSciML you must ensure that the deegreewfs:SuppressXLinkOutput value is false, or absent, otherwise features with the same gml:id will be repeated throughout the document. For example: in our sample configuration gsml:MappedFeature/gsml:specification is of type gsml:GeologicUnit. Multiple gsml:MappedFeatures can have the same gsml:GeologicUnit as its gsml:specification property. Repeated instances of a gsml:GeologicUnit must be referenced with an xlink attibute (eg. .) SuppressXLinkOutput = false ensures this.

FeatureType Datasource

The annotation specifying the source table and WFS behaviour for a feature type can be applied to the xsd:element or to the xsd:complexType if the latter is the case can only be used for a single feature type, not reused by others. This example assumes reusable complexTypes.

To configure the gsml:MappedFeature (lines 25 to 36):

   <xsd:element name="MappedFeature" type="gsml:MappedFeatureType" substitutionGroup="gml:_Feature">
      <xsd:annotation>
         <xsd:appinfo>
            <deegreewfs:table>deegree.mappedfeature</deegreewfs:table>
            <deegreewfs:gmlId prefix="gsml.mappedfeature.">
               <deegreewfs:MappingField field="id" type="VARCHAR"/>
               <deegreewfs:IdentityPart>true</deegreewfs:IdentityPart>
            </deegreewfs:gmlId>
            <deegreewfs:visible>true</deegreewfs:visible>
         </xsd:appinfo>
      </xsd:annotation>
   </xsd:element>

deegreewfs:table specifies the source table deegreewfs:gmlId specifies the content of the gml:id, in this case producing something like gml:id="gsml.mappedfeature.158728" deegreewfs:visible specifies whether or not the feature is visible in the GetCapabilities document and therefore served by the WFS.
  • For interim feature types such as gsml:OutcropCharacter that must never be served by a GeoSciML WFS deegreewfs:visible must be set to false.
  • In our sample configuration gsml:GeologicUnit has =deegreewfs:visible set to false for convenience sake. It can be visible, but care must be taken specifying its (optional) gsml:occurrence property, gsml:MappedFeature, as the association between the two types is recursive.

Element values are specified with annotation elements referring to the field in the table specified for the feature type element on each element in the complexType. There are three main ways (see the Deegree documentation for others) to specify values:

Simple types (eg. gsml:MappedFeature/gsml:positionalAccuracy - lines 57 to 65)
   <xsd:element name="positionalAccuracy" type="xsd:string">
      <xsd:annotation>
         <xsd:appinfo>
            <deegreewfs:Content>
               <deegreewfs:MappingField field="positionalAccuracy" type="VARCHAR"/>
            </deegreewfs:Content>
         </xsd:appinfo>
      </xsd:annotation>
   </xsd:element>
Uses the deegreewfs:MappingField to specify the source field.

Constants (eg. gsml:MappedFeature/gsml:samplingFrame - lines 75 to 83)
   <xsd:element name="samplingFrame" type="xsd:string">
      <xsd:annotation>
         <xsd:appinfo>
            <deegreewfs:Content>
               <deegreewfs:Constant>urn:cgi:feature:CGI:EarthNaturalSurface</deegreewfs:Constant>
            </deegreewfs:Content>
         </xsd:appinfo>
      </xsd:annotation>
   </xsd:element>
The value of deegreewfs:Constant is the constant value of the element.

Complex Types (eg. gsml:MappedFeature/gsml:specification - lines 84 to 99)
   <xsd:element name="specification" type="gml:FeaturePropertyType">
      <xsd:annotation>
         <xsd:appinfo>
            <deegreewfs:Content type="gsml:GeologicUnit">
               <deegreewfs:Relation>
                  <deegreewfs:From>
                     <deegreewfs:MappingField field="geologicalfeature_id" type="VARCHAR"/>
                  </deegreewfs:From>
                  <deegreewfs:To fk="false">
                     <deegreewfs:MappingField field="id" type="VARCHAR"/>
                  </deegreewfs:To>
               </deegreewfs:Relation>
            </deegreewfs:Content>
         </xsd:appinfo>
      </xsd:annotation>
   </xsd:element>
deegreewfs:Content refers to the =xsd:element= defining the target feature type deegreewfs:Relation/deegreewfs:From and deegreewfs:Relation/deegreewfs:To define the primary/foreign keys used in each of the two tables that provide the data for the feature types.

These patterns can be repeated for all elements in the schema as shown in GeoSciMLv2.0.xsd.

Deegree (iii): GeoSciML XSL Transformation

Once Deegree is serving data, two XSLT files must be created. One transforms the interim feature types in a response's wfs:FeatureCollection to GeoSciML, the other transforms GeoSciML GetFeature requests in requests against the interim schema.

GeoSciML Response XSLT

This is a collection of xsl:templates for each feature type and relevant complex types. Once processed all interim schema content should be cast or mapped to the relevant GeoSciML nodes.

For example the xsl:template for the gsml:MappedFeature (lines 15 to 36 of sample-deegree-conf.zip -> wfs/xslt/GeoSciMLv2.0-Out.xslt):
   <xsl:template match="gsml:MappedFeature">
      <gsml:MappedFeature gml:id="{@gml:id}">
         <xsl:copy-of select="gml:boundedBy"/>
         <xsl:for-each select="gsml:observationMethod">
            <gsml:observationMethod>
               <gsml:CGI_TermValue>
                  <gsml:value codeSpace="{gsml:ObservationMethod/gsml:value_codeSpace}"><xsl:value-of select="gsml:ObservationMethod/gsml:value"/></gsml:value>
               </gsml:CGI_TermValue>
            </gsml:observationMethod>
         </xsl:for-each>
         <gsml:positionalAccuracy>
            <gsml:CGI_TermValue>
               <gsml:value codeSpace="{gsml:positionalAccuracy_codeSpace}"><xsl:value-of select="gsml:positionalAccuracy"/></gsml:value>
            </gsml:CGI_TermValue>
         </gsml:positionalAccuracy>
         <gsml:samplingFrame xlink:href="{gsml:samplingFrame}"/>
         <gsml:specification>
            <xsl:apply-templates select="gsml:specification/gsml:GeologicUnit"/>
         </gsml:specification>
         <xsl:apply-templates select="gsml:shape"/>
      </gsml:MappedFeature>
   </xsl:template>
Where necessary this template calls other templates.

Note that is is important that this template handles the full GetFeature response, ensuring the everything is properly populated, especially the xsi:schemaLocation which must point to the a GeoSciML XSD, not the interim schema.

See lines 7 to 11 of sample-deegree-conf.zip -> wfs/xslt/GeoSciMLv2.0-Out.xslt:
   <xsl:template match="wfs:FeatureCollection">
      <wfs:FeatureCollection numberOfFeatures="{@numberOfFeatures}" xsi:schemaLocation="urn:cgi:xmlns:CGI:GeoSciML:2.0 http://www.geosciml.org/geosciml/2.0/xsd/geosciml.xsd http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
         <xsl:apply-templates/>
      </wfs:FeatureCollection>
   </xsl:template>

GeoSciML Request XSLT

The request XSLT - sample-deegree-conf.zip -> wfs/xslt/GeoSciMLv2.0-In.xslt - evaluates the XPath in ogc:PropertyName elements in a GetFeature request and maps them from GeoSciML to the interim schema. It uses a 'function template' which takes the ogc:PropertyName value and compares it with a hard coded lists, changing it when a match is found.

A shortcoming of this approach is that it is a straight string match and assumes every request will use the same XPath, including namespace prefixes

Deployment

Once the preceding steps are completed the Deegree wfs_configuration.xml (sample-deegree-conf.zip -> wfs/wfs_configuration.xml) is updated to bind the XSLT to the feature types to be transformed.

Other parts of the document are updated with details specific to the Service Provider as this document forms the basis of the WFS's GetCapabilities response.

Note: Although Deegree lets you specify any number of output formats created using XSLT this example will apply the XSL tranform to the default (and mandatory) output format text/xml; subtype=gml/3.1.1 as GeoSciML services are expected to return GeoSciML by default (aren't they?).

The following example is from lines 139 to 158 of sample-deegree-conf.zip -> wfs/wfs_configuration.xml

   <wfs:FeatureTypeList>
      <wfs:FeatureType xmlns:gsml="urn:cgi:xmlns:CGI:GeoSciML:2.0">
         <wfs:Name>gsml:MappedFeature</wfs:Name>
         <wfs:Title>GeoSciML v2.0 MappedFeature - GeologicUnit</wfs:Title>
         <wfs:Abstract>Sample MappedFeatures specified with GeologicUnits for GeoSciML v2.0</wfs:Abstract>
         <ows:Keywords>
            <ows:Keyword>GeoSciML</ows:Keyword>
            <ows:Keyword>GSV</ows:Keyword>
         </ows:Keywords>
         <wfs:DefaultSRS>EPSG:4326</wfs:DefaultSRS>
         <wfs:OutputFormats>
            <wfs:Format deegree:outFilter="./xslt/GeoSciMLv2.0-Out.xslt" deegree:inFilter="./xslt/GeoSciMLv2.0-In.xslt" deegree:schemaLocation="http://www.geosciml.org/geosciml/2.0/xsd/geologicFeature.xsd">text/xml; subtype=gml/3.1.1</wfs:Format>
         </wfs:OutputFormats>
         <ows:WGS84BoundingBox>
            <ows:LowerCorner>143 -39</ows:LowerCorner>
            <ows:UpperCorner>145 -35</ows:UpperCorner>
         </ows:WGS84BoundingBox>
      </wfs:FeatureType>
   </wfs:FeatureTypeList>

The key section is wfs:OutputFormats and the deegree prefixed attributes on wfs:Format:
  • deegree:outFilter specifies the location of the XSL transform for the GeoSciML response;
  • deegree:outFilter specifies the location of the XSL transform for the GeoSciML request; and
  • deegree:schemaLocation points to the relevant GeoSciML XSD for the feature. If this is not populated then the WFS will respond to DescribeFeatureType requests with the interim schema's XSD.

The service should now serve valid GeoSciML.

Advanced Configuration: GeoSciML Functions

There are a variety of ways to implement GeoSciML functions and the Geological Survey of Canada documention (Testbed3FunctionImplementation) is valuable background reading. GSV successfully implemented functions using the method outlined at link to come.

Appendix One: Deegree Application Schema Limitations

The following limitations of Deegree v2.x mean it cannot be used to serve feature types directly from an application schema:
  • Complex types (Types, Data Types and certain Simple Types) must be served as feature types;
  • Attribute values of elements cannot be populated (eg. gml:name/@codeSpace);
  • Only one namespace is allowed for each feature type;
  • Aspatial elements inherited from GML (eg. gml:name) cannot be populated; and
  • in Deegree feature type schema not supported (double check this).

Appendix Two: Mediation Points

The configuration example above assumed that the majority of the mapping between the local database schema and the GeoSciML schema was done in the database and that the Deegree schema as a close approximation of GeoSciML. This represents one end member of a spectrum of mapping and configuration options that could be used create a GeoSciML WFS.

At the other end of the spectrum Deegree could be configured to match the database schema almost exactly and the mapping to GeoSciML could occur in the XSL transform. This may well reduce the number of views required in the database and could improve performance (although this is only speculation and has not been tested). A shortcoming of this approach is that the XSLT will almost certainly become much more complex.

It is likely that the best approach will lie somewhere between these end members and will be dictated by local conditions and requirements. But, put simply: if the service accepts valid GeoSciML requests and produces valid GeoSciML responses then your solution is, in itself, valid. This section is intended to be a discussion of the possible approaches and their advantages and disadvantages.

More coming soon ...

Appendix Three: GetCapabilities Fix

Stable versions of deegree do not remove Deegree application attributes from wfs:Format elements in the GetCapabilities document. For example:
<wfs:Format deegree:inFilter="file:GeoSciMLv2.0-In.xslt" deegree:outFilter="file:GeoSciMLv2.0-Out.xslt"
deegree:schemaLocation="http://www.geosciml.org/geosciml/2.0/xsd/geologicStructure.xsd">text/xml; subtype=gml/3.1.1</wfs:Format>
Consequently GetCapabilities request responses do not validate. This bug has been fixed in the nightly build of Deegree for v2.3.

There are several ways to correct this error:
  1. Replace the deegree2.jar file in [Deegree Install Path]/WEB-INF/lib with the nightly build (deegree2.jar) from the Deegree site. Simplest option.
  2. Use a static GetCapabilities document and redirect GetCapabilities requests to this document using (for example) Apache. This approach is useful if you don't want to upgrade to an unstable version of Deegree or use an earlier version (eg. v2.1 to enable functions as per #Advanced_Configuration_GeoSciML.)
Topic attachments
I Attachment Action Size Date Who Comment
DeegreeArchitecture.pngpng DeegreeArchitecture.png manage 9.9 K 22 Apr 2009 - 11:26 AlistairRitchie Mud map of the Deegree Architecture
sample-deegree-conf.zipzip sample-deegree-conf.zip manage 15.0 K 22 Apr 2009 - 10:13 AlistairRitchie Sample Deegree WFS GeoSciML configuration folder.
Topic revision: r14 - 15 Oct 2010, UnknownUser
 

Current license: All material on this collaboration platform is licensed under a Creative Commons Attribution 3.0 Australia Licence (CC BY 3.0).