2

EDIT: This appears to be a version dependent issue! When I posted the question I was using Geoserver 2.11.1. I upgraded to the 2.12 nightly SNAPSHOT and I can now general GeodesyML output. The problem I'm currently solving is why my WFS returns a .application file with GeodesyML output that is totally unformatted.

Background Info:

My question is generally how to construct a mapping file for the GeodesyML schema but I think it will be useful to provide some background since very few people seem to be familiar with GeodesyML. I want to use Geoserver to serve GPS monument metadata from a PostGIS database and output XML according to the GeodesyML schema definition. I have regular GML output working (in a separate Geoserver workspace) so I know my database is accessible and I'm now trying to create the mapping from my database schema to the GeodesyML schema. See links below also.

Specific Question:

Why are my mapped features site_name to siteName and station_id to fourCharacterID not showing up in my WFS request output and how can I fix it? I believe my issue lies in my XPath given to in my mapping file below. I think I am missing something to deal with abstract XML types (most GeodesyML types are abstract) and Geoserver is getting confused. For example when I send a request to Geoserver such as

http://localhost:8080/geoserver/ows?service=WFS&version=1.1.0&request=GetFeature&typeName=gps_as:GeodesyML&outputFormat=gml32&maxFeatures=3

which specifies WFS version 1.1.0 and GML version 3.2 and limits the response to 3 items, I get a response like

<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:gps_as="urn:xml-gov-au:icsm:egeodesy:0.4" 
xmlns:gml="http://www.opengis.net/gml/3.2" 
xmlns:gps="http://geoserver.org/gps" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
numberMatched="unknown" numberReturned="3" timeStamp="2017-06-20T19:17:19.347Z" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://localhost:8080/geoserver/schemas/wfs/2.0/wfs.xsd urn:xml-gov-au:icsm:egeodesy:0.4 https://raw.githubusercontent.com/GeoscienceAustralia/GeodesyML/master/schemas/geodesyML.xsd http://www.opengis.net/gml/3.2 
http://localhost:8080/geoserver/schemas/gml/3.2.1/gml.xsd">
<wfs:member>
<gps_as:GeodesyML gml:id="geoml_monuments.fid--43c4ca2_15cc63f75d5_-7f5a"/>
</wfs:member>
<wfs:member>
<gps_as:GeodesyML gml:id="geoml_monuments.fid--43c4ca2_15cc63f75d5_-7f59"/>
</wfs:member>
<wfs:member>
<gps_as:GeodesyML gml:id="geoml_monuments.fid--43c4ca2_15cc63f75d5_-7f58"/>
</wfs:member>
</wfs:FeatureCollection>

Relevant Links:

Here is the GeodesyML github page, including the .xsd files for GeodesyML: http://github.com/GeoscienceAustralia/geodesyml

Here is an interactive schema map for GeodesyML: http://geoscienceaustralia.github.io/GeodesyML-Github-Pages/

Here is documentation on how to create a mapping file for Geoserver App-Schema: http://docs.geoserver.org/stable/en/user/data/app-schema/mapping-file.html

Here is a tutorial on creating a (very simple) mapping file for GeoSciML: http://docs.geoserver.org/stable/en/user/data/app-schema/tutorial.html

Here is a blog post on making a mapping file for GeoSciML: http://lab.usgin.org/groups/building-geosciml-wfs-server/ncgmp-geosciml-mappedfeature

My Mapping File:

<?xml version="1.0" encoding="UTF-8"?>
<as:AppSchemaDataAccess 
xmlns:as="http://www.geotools.org/app-schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.geotools.org/app-schema AppSchemaDataAccess.xsd">
<namespaces>
    <Namespace>
        <prefix>geo</prefix>
        <uri>urn:xml-gov-au:icsm:egeodesy:0.4</uri>
    </Namespace>
    <Namespace>
        <prefix>gml</prefix>
        <uri>http://www.opengis.net/gml/3.2</uri>
    </Namespace>
    <Namespace>
        <prefix>gmd</prefix>
        <uri>http://www.isotc211.org/2005/gmd</uri>
    </Namespace>
</namespaces>
<includedTypes></includedTypes>
<sourceDataStores>
    <DataStore>
        <id>thedb</id>
        <parameters>
            <Parameter>
                <name>dbtype</name>
                <value>postgisng</value>
            </Parameter>
            <Parameter>
                <name>host</name>
                <value>fakeurl.unavco.org</value>
            </Parameter>
            <Parameter>
                <name>port</name>
                <value>5432</value>
            </Parameter>
            <Parameter>
                <name>database</name>
                <value>fakedb</value>
            </Parameter>
            <Parameter>
                <name>user</name>
                <value>fakeusername</value>
            </Parameter>
            <Parameter>
                <name>passwd</name>
                <value>fakepassword</value>
            </Parameter>
        </parameters>
    </DataStore>
</sourceDataStores>
<catalog></catalog>
<targetTypes>
    <FeatureType>
        <!--<schemaUri>http://localhost/geodesyML_schemas/geodesyML.xsd</schemaUri>-->
        <schemaUri>https://raw.githubusercontent.com/GeoscienceAustralia/GeodesyML/master/schemas/geodesyML.xsd</schemaUri>
    </FeatureType>
</targetTypes>
<typeMappings>
    <FeatureTypeMapping>
        <sourceDataStore>thedb</sourceDataStore>
        <sourceType>geoml_monuments</sourceType>
        <!-- geoml_monuments is a materialized view in the postGIS database and it is used as the source schema, or the schema we are mapping FROM -->
        <targetElement>geo:GeodesyML</targetElement>
        <!-- is the root element of the target schema, GeodesyML -->
        <attributeMappings>
            <!--<AttributeMapping>
                <targetAttribute>geo:GeodesyML</targetAttribute>
                <targetAttributeNode>geo:GeodesyMLPropertyType</targetAttributeNode>
            </AttributeMapping>
            <AttributeMapping>
                <targetAttribute>geo:AbstractSiteLog</targetAttribute>
                <targetAttributeNode>geo:SiteLogType</targetAttributeNode>
            </AttributeMapping>-->
            <AttributeMapping>
                <targetAttribute>geo:siteLog/geo:siteIdentification/geo:siteName</targetAttribute>
                <sourceExpression><OCQL>site_name</OCQL></sourceExpression>
                <encodeIfEmpty>true</encodeIfEmpty>
            </AttributeMapping>
            <AttributeMapping>
                <targetAttribute>geo:siteLog/geo:siteIdentification/geo:fourCharacterID</targetAttribute>
                <sourceExpression><OCQL>station_code</OCQL></sourceExpression>
                <encodeIfEmpty>true</encodeIfEmpty>
            </AttributeMapping>
        </attributeMappings>
    </FeatureTypeMapping>
</typeMappings>

0

2 Answers 2

3

I am the technical lead of GA’s effort to adopt GeodesyML. I see that you’ve solved your problem by upgrading to a later version of GeoServer. I would like to suggest a slightly different approach to your mapping and share with you our own implementation of a GeodesyML web feature service, which you may find helpful.

Our interpretation is that GeodesyML root element exists for use outside of the OGC/WFS context. Parties may wish to exchange GodesyML documents, by means other than WFS, containing multiple entities, as in the following example:

MOBS.xml

For your WFS service, perhaps you could consider defining a feature type called SiteLog to generate responses of the form:

<wfs:member>
    <geo:SiteLog>
        <geo:siteIdentification>
            <geo:fourCharacterId>…</geo:fourCharacterId>
            <geo:siteName>…</geo:siteName>
             …
        </geo:siteIdentification>
    </geo:SiteLog>
     …
</wfs:member>

Web feature services can return any XML type that is a subtype of GML AbstractFeatureType. This approach would allow you to implement multiple GeodesyML WFS services returning different feature types like geo:SiteLog, geo:Site, geo:Setup, geo:Node, which are all top-level entities, in the sense that they are all subtypes of GML AbstractFeatureType. Otherwise, I don’t know how would clients of a single feature type called geo:GeodesyML specify what information they are interested in. SiteLog is just one entity type modelled by GeodesyML.

Here is a link to the data directory of a GeoServer 2.9.1 instance at Geoscience Australia that implements WFS feature type geo:Site:

https://github.com/GeoscienceAustralia/Geodesy-Web-Services/tree/next/gws-geoserver/data

This service drives the search screen for our GNSS Site Manager web application, which is currently in development.

Here is a sample query:

<wfs:Query typeNames="geo:Site">
    <fes:Or>
        <fes:PropertyIsEqualTo>
            <fes:Literal>true</fes:Literal>
            <fes:Function name="isLike">
                <fes:ValueReference>gml:identifier</fes:ValueReference>
                <fes:Literal>(?i)ad.*</fes:Literal>
            </fes:Function>
        </fes:PropertyIsEqualTo>
        <fes:PropertyIsEqualTo>
            <fes:Literal>true</fes:Literal>
            <fes:Function name="isLike">
                <fes:ValueReference>gml:name</fes:ValueReference>
                <fes:Literal>(?i).*ad.*</fes:Literal>
            </fes:Function>
        </fes:PropertyIsEqualTo>
    </fes:Or>
    <fes:SortBy>
        <fes:SortProperty>
            <fes:ValueReference>gml:identifier</fes:ValueReference>
        </fes:SortProperty>
  </fes:SortBy>
</wfs:Query>

and the response:

<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:geo="urn:xml-gov-au:icsm:egeodesy:0.4" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" numberMatched="unknown" numberReturned="4" timeStamp="2017-06-21T23:01:54.436Z" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://testgeodesy-geoserver.geodesy.ga.gov.au:80/geoserver/schemas/wfs/2.0/wfs.xsd urn:xml-gov-au:icsm:egeodesy:0.4 http://schemas.ga.gov.au/geodesyml/0.4/geodesyML.xsd http://www.opengis.net/gml/3.2 http://testgeodesy-geoserver.geodesy.ga.gov.au:80/geoserver/schemas/gml/3.2.1/gml.xsd">
   <wfs:member>
      <geo:Site gml:id="Site.852">
         <gml:identifier codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteIdentifier">ADE1</gml:identifier>
         <gml:name codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteName">Australia NGA collocated</gml:name>
         <geo:type codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteType">CORS</geo:type>
      </geo:Site>
   </wfs:member>
   <wfs:member>
      <geo:Site gml:id="Site.895">
         <gml:identifier codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteIdentifier">QUI3</gml:identifier>
         <gml:name codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteName">Ecuador NGA colocated</gml:name>
         <geo:type codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteType">CORS</geo:type>
      </geo:Site>
   </wfs:member>
   <wfs:member>
      <geo:Site gml:id="Site.878">
         <gml:identifier codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteIdentifier">QUI4</gml:identifier>
         <gml:name codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteName">Ecuador NGA colocated</gml:name>
         <geo:type codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteType">CORS</geo:type>
      </geo:Site>
   </wfs:member>
   <wfs:member>
      <geo:Site gml:id="Site.861">
         <gml:identifier codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteIdentifier">WSRT</gml:identifier>
         <gml:name codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteName">Westerbork Synthesis Radio Telescope</gml:name>
         <geo:type codeSpace="urn:xml-gov-au:icsm:egeodesy:0.4:SiteType">CORS</geo:type>
      </geo:Site>
   </wfs:member>
</wfs:FeatureCollection>

I know that this does not directly answer your question, but instead proposes a slightly different approach, which may side-step your current problem and also be a better way forward. Please let me know what you think.

3
  • Please do not include signatures in your posts as they may be perceived as spam. Thank you!
    – NobodyNada
    Commented Jun 22, 2017 at 2:20
  • This is really good information on the GA implementation of a GeodesyML mapping. I see that you are defining a custom feature type geo:SiteLog. In my approach, instead of defining anything new, I simply used the GeodesyML root element so I can get <wfs:member><geo:GeodesyML><geo:siteLog>...</geo:siteLog><geo:Site>...</geo:Site></geo:GeodesyML></wfs:member>
    – medley56
    Commented Jun 22, 2017 at 15:53
  • Lazar, could you please explain further about defining feature types? The example you gave (geo:Site) already exists as an element: geo:GeodesyML/geo:Site. How would I go about defining a NEW feature type, e.g. geo:SiteLog that does not exist as an element? Where would I put the file containing that definition?
    – medley56
    Commented Jun 26, 2017 at 23:08
0

Upgraded to Geoserver 2.12 nightly build and it works. Perhaps there is a way to use app schema and GeodesyML in version 2.11.1 but I guess the app schema tutorials use for 2.12 for a reason.

UPDATE: The fix has been backported to the most recent release of Geoserver 2.11.2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.