Skip to main content

I am trying to create a GML file that complies to the GML simple features profile (GML-SF) (http://portal.opengeospatial.org/files/?artifact_id=42729). I already created a GML application schema that complies to the GML simple features profile. It follows the pattern described in GML-SF, 8.4.2:

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ex="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94"
xmlns:gml="http://www.opengis.net/gml/3.2"
elementFormDefault="qualified"
targetNamespace="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94"
version="1.0.0">
<import namespace="http://www.opengis.net/gml/3.2"
schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<element name="FeatureCollection"
type="ex:FeatureCollectionType"
substitutionGroup="gml:AbstractGML"/>
<complexType name="FeatureCollectionType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence minOccurs="0" maxOccurs="unbounded">
<element name="featureMember">
<complexType>
<complexContent>
<extension base="gml:AbstractFeatureMemberType">
<sequence>
<element ref="gml:AbstractFeature"/>
</sequence>
</extension>
</complexContent>
</complexType>
</element>
</sequence>
</extension>
</complexContent>
</complexType>
<!-- ... -->
</schema>

So in an instance file, you would have the following:

<ex:FeatureCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ex="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94"
gml:id="id0d5b6096-585a-4db5-9ac8-a66faf9ecf17">
<ex:featureMember>
<!-- feature 1 -->
</ex:featureMember>
<ex:featureMember>
<!-- feature 2 -->
</ex:featureMember>
<ex:featureMember>
<!-- feature 3 -->
</ex:featureMember>
<ex:featureMember>
<!-- feature 4 -->
</ex:featureMember>
<!-- etc. -->
</ex:FeatureCollection>

I’ve tried to use a FeatureWriter with the GML format, however, I do not get the results I want. I built up a hierarchy of features with gml_id and gml_parent_id, I’ve set parameter “Feature Collection” to “FeatureCollection”, and “Feature Collection NS URI” to the namespace I’m using, but the outcome is something like:

<ex:FeatureCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ex="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94"
gml:id="id0d5b6096-585a-4db5-9ac8-a66faf9ecf17">
<ex:featureMember>
<!-- feature 1 -->
<!-- feature 2 -->
<!-- feature 3 -->
<!-- feature 4 -->
<!-- etc. -->
</ex:featureMember>
</ex:FeatureCollection>

So the ex:featureMember is only present once.

When changing “Feature Collection NS URI” to “http://www.opengis.net/gml/3.2”, the outcome looks better, it is at least GML-compliant:

<gml:FeatureCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ex="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94"
gml:id="id0d5b6096-585a-4db5-9ac8-a66faf9ecf17">
<gml:featureMember>
<!-- feature 1 -->
</gml:featureMember>
<gml:featureMember>
<!-- feature 2 -->
</gml:featureMember>
<gml:featureMember>
<!-- feature 3 -->
</gml:featureMember>
<gml:featureMember>
<!-- feature 14-->
</gml:featureMember>
<!-- etc. -->
</gml:FeatureCollection>

What parameters do I need to set to get an GML-file that uses the custom feature collection and that places ex:featureMember correctly, and the correct number of times?

A second question: I would like to give the FeatureCollection a bounding box. I’ve tried to set attribute gml_boundedBy, but it does not show up in the GML file, and when I look at the transformers, it is set to a Surface, whereas I would like to have an Envelope. What do I have to change or add to achieve this?

I am using FME 2023.2.3.0.

I have added a zip-file with my workspace, the GML application schema, and the input and output files I used/got. It’s not real data, just a minimal example to show the issue.

Note: Using the OGC GML SF-0 format instead is not an option:

  • the resulting GML files use the old namespace, http://www.opengis.net/gml
  • the geometry properties are the predefined properties (e.g. gml:pointProperty), but I would like to use e.g. ex:geometry
  • the order of the properties, especially the geometry one, cannot be controlled

 

 

 

I think I would use that xsd that you have to create an XML Template, using the XMLSampleGenerator, then use that template with the XMLTemplater.

That way you have complete control over what ends up in your resulting GML, instead of the FeatureWriter doing it’s own thing.


Thanks a lot! I’ve tried that, and I managed to get the output the way I wanted it by using the XMLTemplater. In its configuration, I used the functionality behind the “Generate” button (from the documentation: “may be used to bring up a dialog which can be used to generate an XML document which may be used as a base for an XML template. This dialog uses the same functionality as the XMLSampleGenerator”) and adjusted the output as needed.

I also managed to add the bounding box of the FeatureCollection itself, by using the BoundsExtractor and the XQuery geometry functions in the XMLTemplater.

<ex:FeatureCollection xmlns:ex="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:uuid:3c615c60-013b-4006-bf53-d0ba4fb5fc94 example.xsd"
gml:id="{fme:get-attribute('gml_id')}">
<gml:boundedBy>
<gml:Envelope srsName="{fme:get-coordinate-system()}"
srsDimension="{geom:get-dimension()}">
<gml:lowerCorner>{fme:get-attribute("_xmin")} {fme:get-attribute("_ymin")}{if (geom:get-dimension() = 3) then ( fme:get-attribute("_zmin")) else ()}</gml:lowerCorner>
<gml:upperCorner>{fme:get-attribute("_xmax")} {fme:get-attribute("_ymax")}{if (geom:get-dimension() = 3) then ( fme:get-attribute("_zmax")) else ()}</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
{fme:process-features("OBJECT1")}
{fme:process-features("OBJECT2")}
</ex:FeatureCollection>

 


Glad you managed to solve it. I’m currently working on exporting specific data to a customised flavour of GML, for an information exchange project, and I did things this way. Took some time, because it can be very fiddly, but the full fine-grained control is quite good.

One of the nice things you can now also do, is use the XMLValidator to validate the resulting xml against the xsd. That way you can be sure that the xml you write/send is valid (sometimes data can break the validity).


Reply