In this demo we read UN gazetteer data and use XMLTemplaters to write complex GML 3.2.1 data compliant with the INSPIRE Annex I Geographic Names application schemas.
The workspace handles the complete process of data transformation and GML generation. The first part of the workspace assembles the source data via the necessary source files and joins, and then transforms it to the INSPIRE schema using SchemaMapper. The second half of the workspace involves taking the relational geographic names data and writing it out as GML 3.2.1 data compliant with the INSPIRE Geographic Names application schemas.
Key Components
Data Assembly
-
Read source shape data
-
Filter data based on user value selection for countries of interest.
-
Use PointOnAreaOverlay to perform a spatial join and combine add supporting attributes to the source gazatteer point features.
Schema Transformation
-
Use FME's schema mapping capabilities to map from source schema to INSPIRE Geographic Names schema.
-
Two possible approaches to schema transformation in FME are illustrated here. Note that only one of these methods should be enabled at any one time or you will get double the number of expected features.
-
Restructuring with FME's AttributeCopier and AttributeValueMapper transformer.
-
Using a cross walk table with FME's SchemaMapper transformer to map from source schema to destination INSPIRE schema. Below are two examples that are used in this workspace. These are just a couple from the many types of mapping rules possible from within SchemaMapper. This is an ideal approach to use when you need domain experts to participate who may not want to learn how to use a new tool.
attribute name mapping
maps source field TEXT to destination name_GeographicalName_nativeValue
conditional value mapping rule
where source CNTRY_NAME = "Italy" create field name_GeographicalName_language and set the value to "Italian"
3. Feature and geometry id generation.
4. Geometry Extraction: CoordinateExtractor generates _x, _y values. It is common in GML writing to use a coordinate or geometry extractor to generate geometry data for use in XMLTemplater.
INSPIRE GML Generation
-
After completing the required schema transforms, an XMLTemplater processes the NamedPlace features into INSPIRE GML. XMLTemplater uses a template of the desired XML structure with XQuery functions embedded where the FME feature attribute values are to be merged in. A sample xml record can serve as the starting point for template creation: see GeographicNamesSample.gml. Note that your main focus is to know where your feature data fits into the XML objects and not so much on the detailed structure of the XML itself. You really only need to understand the XML as much as is needed to get it to propogate your data and to validate the result against the application schema XSDs.
fme:get-attribute(“”} commands are inserted for the following fields in the appropriate locations:
-
name_GeographicalName_featureID
-
name_GeographicalName_pointID
-
_x,_y
-
_uuid
-
name_GeographicalName_namespace
-
name_GeographicalName_language
-
name_GeographicalName_nativeValue
Sample Feature XML Template:
<NamedPlace gml:id="{fme:get-attribute("name_GeographicalName_featureID")}"
xmlns="urn:x-inspire:specification:gmlas:GeographicalNames:3.0" xmlns:base="urn:x-inspire:specification:gmlas:BaseTypes:3.2"
xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:x-inspire:specification:gmlas:GeographicalNames:3.0 ../XSD/GeographicalNames.xsd">
<beginLifespanVersion>2010-01-01T12:00:00</beginLifespanVersion>
<geometry>
<gml:Point gml:id="{fme:get-attribute("name_GeographicalName_pointID")}" srsName="urn:ogc:def:crs:EPSG::4258">
<gml:pos>{fme:get-attribute("_x")} {fme:get-attribute("_y")}</gml:pos>
</gml:Point>
</geometry>
<inspireId>
<base:Identifier>
<base:localId>{fme:get-attribute("_uuid")}</base:localId>
<base:namespace>{fme:get-attribute("name_GeographicalName_namespace")}</base:namespace>
</base:Identifier>
</inspireId>
<localType>
<gmd:LocalisedCharacterString locale="en-GB">{fme:get-attribute("typeLocal")}</gmd:LocalisedCharacterString>
</localType>
<name>
<GeographicalName>
<language>{fme:get-attribute("name_GeographicalName_language")}</language>
<nativeness>endonym</nativeness>
<nameStatus>standardised</nameStatus>
<sourceOfName/>
<pronunciation>
<PronunciationOfName/>
</pronunciation>
<spelling>
<SpellingOfName>
<text>{fme:get-attribute("name_GeographicalName_nativeValue")}</text>
<script>Latn</script>
</SpellingOfName>
</spelling>
</GeographicalName>
</name>
<type>Administrative unit</type>
</NamedPlace>
This generates the xml needed for each Geographic Name record. Note that we need the name space declarations on every feature in order for this to be valid XML. These redundant declarations will get cleaned up later by the XMLFormater.
3. The ListBuilder assembles them into a single list per feature type.
4. Another XMLTemplater is used to assemble the XML for the dataset.
Sample dataset XML template:
<?xml version="1.0" encoding="UTF-8"?>
<gml:FeatureCollection gml:id="AT.HR.IT.0" xmlns="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
xmlns:base="urn:x-inspire:specification:gmlas:BaseTypes:3.2"
xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:x-inspire:specification:gmlas:GeographicalNames:3.0 ../XSD/GeographicalNames.xsd">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4258">
<gml:lowerCorner>7.0 35.0</gml:lowerCorner>
<gml:upperCorner>20.0 50.0</gml:upperCorner>
</gml:Envelope></gml:boundedBy>
<gml:featureMembers>
{fme:get-xml-list-attribute("_list{}._features")}
</gml:featureMembers>
</gml:FeatureCollection>
5. XMLFormatter to pretty print our output GML and clean-up of redundant namespace declarations.
6. The XMLValidator validates the output XML for syntax and application schema validity using
GeographicalNames.xsd
7. Finally, we use the Text File writer to write out GeographicNames.gml.
The reason we use this writer is that the schema generation is handled by the XMLTemplater. The Text File writer is an easy way to write XML to disk without imposing any schema on the writer itself. If we used an XML writer then we would have to structure the entire schema in the destination XML feature type, and perhaps use XSLT for post processing to support complex constructs requried for INSPIRE GML.
When you run the demo, confirm that your XML validates both for syntax and against the INSPIRE application schemas. Also, confirm that you have created valid INSPIRE GML by reading it with the GML reader. As of FME 2012 there is no need to manually specify the Annex I INSPIRE application schemas. FME ships with these and automatically recognizes and reads INSPIRE data.
Note while this demo yields INSPIRE compliant GML, it is included here for demo purposes only, does not populate all optional fields, and uses default field values in many cases. Still, the logic and patterns shown here are relevant to any transformation for reading multiple data sources, transforming to an INSPIRE schema and writing to INSPIRE schema compliant GML.