1

When attempting to write out GML encoded features that were originally collected using the Geotools WFS plugin (gt-wfs-ng), it looks like the GML output is incorrectly duplicating the feature's prefix and producing incorrect xml. For example, a simplified version of what I'm trying to do looks like this:

    Map<String, String> wfsParams = new HashMap<String, String>();

    wfsParams.put(
            "WFSDataStoreFactory:GET_CAPABILITIES_URL",
            "https://mrdata.usgs.gov/wfs/asbestos?service=WFS&REQUEST=GetCapabilities");

    wfsParams.put("WFSDataStoreFactory:WFS_STRATEGY", "mapserver");

    DataStore store = DataStoreFinder.getDataStore(wfsParams);

    SimpleFeatureType schema = store.getSchema("ms:asbestos");

    FeatureSource<SimpleFeatureType, SimpleFeature> source = store.getFeatureSource("ms:asbestos");

    Query query = new Query(schema.getTypeName());
    query.setMaxFeatures(2);

    FeatureCollection<SimpleFeatureType, SimpleFeature> features = source.getFeatures(query);

    GML encode = new GML(Version.WFS1_1);

    Name schemaName = schema.getName();

    String prefix = schemaName.getLocalPart().split(":")[0];
    String uri = schemaName.getNamespaceURI();

    encode.setNamespace(prefix, uri);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    SimpleFeatureCollection simpleCollection = DataUtilities.simple(features);
    encode.encode(baos, simpleCollection);

    System.out.println(baos.toString());

The output I get from that snippit looks like this:

<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns:ms="http://mapserver.gis.umn.edu/mapserver" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink">
  <gml:boundedBy>
    <gml:Envelope srsDimension="2" srsName="urn:x-ogc:def:crs:EPSG:4326">
      <gml:lowerCorner>-73.0 -179.0</gml:lowerCorner>
      <gml:upperCorner>81.0 180.0</gml:upperCorner>
    </gml:Envelope>
  </gml:boundedBy>
  <gml:featureMembers>
    <ms:ms:asbestos gml:id="asbestos.850">
      <gml:boundedBy>
        <gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326" srsDimension="2">
          <gml:lowerCorner>35.783268 -116.204155</gml:lowerCorner>
          <gml:upperCorner>35.783268 -116.204155</gml:upperCorner>
        </gml:Envelope>
      </gml:boundedBy>
      <ms:geometry>
        <gml:Point srsName="urn:x-ogc:def:crs:EPSG:4326" srsDimension="3">
          <gml:pos>35.783268 -116.204155</gml:pos>
        </gml:Point>
      </ms:geometry>
      <ms:rec_id>1046</ms:rec_id>
      <ms:site_name>Amargosa mine</ms:site_name>
      <ms:devel/>
      <ms:fips_code>f06071</ms:fips_code>
      <ms:huc_code>h18090203</ms:huc_code>
      <ms:quad_code>q36118NEG2</ms:quad_code>
      <ms:url>https://mrdata.usgs.gov/asbestos/show-asbestos.php?rec_id=1046</ms:url>
      <ms:oremin/>
      <ms:assocmin/>
    </ms:ms:asbestos>
    <ms:ms:asbestos gml:id="asbestos.851">
      <gml:boundedBy>
        <gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326" srsDimension="2">
          <gml:lowerCorner>35.782971 -116.00875</gml:lowerCorner>
          <gml:upperCorner>35.782971 -116.00875</gml:upperCorner>
        </gml:Envelope>
      </gml:boundedBy>
      <ms:geometry>
        <gml:Point srsName="urn:x-ogc:def:crs:EPSG:4326" srsDimension="3">
          <gml:pos>35.782971 -116.00875</gml:pos>
        </gml:Point>
      </ms:geometry>
      <ms:rec_id>1047</ms:rec_id>
      <ms:site_name>Rogers mine</ms:site_name>
      <ms:devel/>
      <ms:fips_code>f06071</ms:fips_code>
      <ms:huc_code>h18090202</ms:huc_code>
      <ms:quad_code>q36118NEH2</ms:quad_code>
      <ms:url>https://mrdata.usgs.gov/asbestos/show-asbestos.php?rec_id=1047</ms:url>
      <ms:oremin/>
      <ms:assocmin/>
    </ms:ms:asbestos>
  </gml:featureMembers>
</wfs:FeatureCollection>

Notice that in the xml output, features members are named "ms:ms:asbestos" instead of just "ms:asbestos". I've tried modifying the values passed to the encode.setNamespace(), but while I can change the value of the first prefix I cannot turn it off. Setting values of "" or null just results in a prefix named null (i.e. "null:ms:asbestos").

Why is geotools adding the additional prefix? How do I prevent it from doing so?

  • Is ms defined correctly in the input? – Ian Turton Apr 2 '18 at 17:23
  • @IanTurton I'm not sure, how would you recommend I go about checking that? – TwentyMiles Apr 2 '18 at 17:25
  • Grab the wfs response in a browser – Ian Turton Apr 2 '18 at 17:26
  • Yes, if you check the WFS response without going through geotools, the prefixing is correct. See this link for an example. – TwentyMiles Apr 2 '18 at 17:29
1

This looks like a bug, but I'm not sure where it is!

The schema looks like:

<?xml version='1.0' encoding="ISO-8859-1" ?>
<schema
   targetNamespace="http://mapserver.gis.umn.edu/mapserver" 
   xmlns:ms="http://mapserver.gis.umn.edu/mapserver" 
   xmlns:ogc="http://www.opengis.net/ogc"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns="http://www.w3.org/2001/XMLSchema"
   xmlns:gml="http://www.opengis.net/gml"
   elementFormDefault="qualified" version="0.1" >

  <import namespace="http://www.opengis.net/gml"
          schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />

  <element name="asbestos" 
           type="ms:asbestosType" 
           substitutionGroup="gml:_Feature" />

  <complexType name="asbestosType">
    <complexContent>
      <extension base="gml:AbstractFeatureType">
        <sequence>
          <element name="geometry" type="gml:PointPropertyType" minOccurs="0" maxOccurs="1"/>
          <element name="rec_id" type="string"/>
          <element name="site_name" type="string"/>
          <element name="devel" type="string"/>
          <element name="fips_code" type="string"/>
          <element name="huc_code" type="string"/>
          <element name="quad_code" type="string"/>
          <element name="url" type="string"/>
          <element name="oremin" type="string"/>
          <element name="assocmin" type="string"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

</schema>

and the FeatureCollection is:

<?xml version='1.0' encoding="ISO-8859-1" ?>
<wfs:FeatureCollection
   xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
   xmlns:gml="http://www.opengis.net/gml"
   xmlns:wfs="http://www.opengis.net/wfs"
   xmlns:ogc="http://www.opengis.net/ogc"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver https://mrdata.usgs.gov/wfs/asbestos?SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=ms:asbestos&amp;OUTPUTFORMAT=text/xml;%20subtype=gml/3.1.1  http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
      <gml:boundedBy>
        <gml:Envelope srsName="EPSG:4326">
            <gml:lowerCorner>30.478092 -123.713582</gml:lowerCorner>
            <gml:upperCorner>48.988906 -67.995471</gml:upperCorner>
        </gml:Envelope>
      </gml:boundedBy>
    <gml:featureMember>
      <ms:asbestos gml:id="asbestos.850">
        <gml:boundedBy>
            <gml:Envelope srsName="EPSG:4326">
                <gml:lowerCorner>35.783268 -116.204155</gml:lowerCorner>
                <gml:upperCorner>35.783268 -116.204155</gml:upperCorner>
            </gml:Envelope>
        </gml:boundedBy>
        <ms:geometry>
          <gml:Point srsName="EPSG:4326">
            <gml:pos>35.783268 -116.204155</gml:pos>
          </gml:Point>
        </ms:geometry>
        <ms:rec_id>1046</ms:rec_id>
        <ms:site_name>Amargosa mine</ms:site_name>
        <ms:devel></ms:devel>
        <ms:fips_code>f06071</ms:fips_code>
        <ms:huc_code>h18090203</ms:huc_code>
        <ms:quad_code>q36118NEG2</ms:quad_code>
        <ms:url>https://mrdata.usgs.gov/asbestos/show-asbestos.php?rec_id=1046</ms:url>
        <ms:oremin></ms:oremin>
        <ms:assocmin></ms:assocmin>
      </ms:asbestos>
    </gml:featureMember>

    .....

Which look plausible to me, when GeoTools reads them it gets the following:

SimpleFeatureTypeImpl http://mapserver.gis.umn.edu/mapserver:ms:asbestos identified extends Feature(geometry:geometry,rec_id:rec_id,site_name:site_name,devel:devel,fips_code:fips_code,huc_code:huc_code,quad_code:quad_code,url:url,oremin:oremin,assocmin:assocmin)

SimpleFeatureImpl:ms:asbestos=[SimpleFeatureImpl.Attribute: geometry<geometry id=asbestos.850>=POINT (35.783268 -116.204155), SimpleFeatureImpl.Attribute: rec_id<rec_id id=asbestos.850>=1046, SimpleFeatureImpl.Attribute: site_name<site_name id=asbestos.850>=Amargosa mine, SimpleFeatureImpl.Attribute: devel<devel id=asbestos.850>=, SimpleFeatureImpl.Attribute: fips_code<fips_code id=asbestos.850>=f06071, SimpleFeatureImpl.Attribute: huc_code<huc_code id=asbestos.850>=h18090203, SimpleFeatureImpl.Attribute: quad_code<quad_code id=asbestos.850>=q36118NEG2, SimpleFeatureImpl.Attribute: url<url id=asbestos.850>=https://mrdata.usgs.gov/asbestos/show-asbestos.php?rec_id=1046, SimpleFeatureImpl.Attribute: oremin<oremin id=asbestos.850>=, SimpleFeatureImpl.Attribute: assocmin<assocmin id=asbestos.850>=]

Which again looks good. That seems to point the finger at the encoder.

I switched to a different encoder:

org.geotools.xml.Configuration configuration = new org.geotools.gml3.GMLConfiguration();
org.geotools.xml.Encoder encoder = new org.geotools.xml.Encoder(configuration);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
encoder.setNamespaceAware(true);
encoder.setIndenting(true);
SimpleFeatureCollection simpleCollection = DataUtilities.simple(features);
encoder.encode(simpleCollection, GML.FeatureCollection, baos);
System.out.println(baos.toString());

which gives:

<gml:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns:xlink="http://www.w3.org/1999/xlink">
  <gml:featureMembers>
    <null:asbestos xmlns:null="http://mapserver.gis.umn.edu/mapserver" gml:id="asbestos.850">
      <gml:boundedBy>
        <gml:Envelope srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
          <gml:lowerCorner>35.783268 -116.204155</gml:lowerCorner>
          <gml:upperCorner>35.783268 -116.204155</gml:upperCorner>
        </gml:Envelope>
      </gml:boundedBy>
      <null:geometry>
        <gml:Point srsDimension="3" srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
          <gml:pos>35.783268 -116.204155</gml:pos>
        </gml:Point>
      </null:geometry>
      <null:rec_id>1046</null:rec_id>
      <null:site_name>Amargosa mine</null:site_name>
      <null:devel/>
      <null:fips_code>f06071</null:fips_code>
      <null:huc_code>h18090203</null:huc_code>
      <null:quad_code>q36118NEG2</null:quad_code>
      <null:url>https://mrdata.usgs.gov/asbestos/show-asbestos.php?rec_id=1046</null:url>
      <null:oremin/>
      <null:assocmin/>
    </ms:asbestos>

Note how just the closing feature tag has an ms prefix, which is very odd.

For now could you raise a bug with your test code included and a link back to this question.

  • Thanks for taking the time to look at this. I agree that it seems like it's probably a bug. I'll take a look at filing a bug report, but since gt-wfs-ng is currently an "unsupported" plugin, I don't have high expectations of it being fixed any time soon. – TwentyMiles Apr 3 '18 at 18:43
  • The encoder is supported though which was why I was trying to narrow it down – Ian Turton Apr 3 '18 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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