Skip to main content

Edition: FME Oracle Edition (node locked-crc)

 

Version: FME(R) 2016.1.1.0 (20160722 - Build 16609 - WIN64)

 

Locale: en_US

 

Codepage: 1252 (ANSI - Latin I)

 

Registration Key: 1-628-344-195

 

Registration: Evaluation License 361 days left

 

Serial Number: NBGL-UEC6-12L8

 

Customer Number: 95780

 

Home Folder: C:\\Program Files\\FME\\

 

Operating System: Microsoft Windows 10 64-bit (Build 10586)

I am converting some linear data in an ESRI File GeoDatabase to GML using the GML SF-0 writer.

I then load that data in to SQL Server 2012 for conversion into geography instances.

The FME data has namespace prefixes for every tag:

<fme:FeatureCollection xmlns:fme="http://www.safe.com/gml/fme" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" gml:id="id78f185fa-6116-47e5-b873-8d66e48aa1dc">

<fme:featureMember>

<fme:Roads gml:id="idd3bb702b-f7a7-4207-ae24-f509a179f511">

<fme:OBJECTID>1</fme:OBJECTID>

<fme:STREET>MIDDLE ROAD</fme:STREET>

<fme:ROADTYPE>5</fme:ROADTYPE>
<fme:Shape_Length>0.00582176844494881</fme:Shape_Length>

<fme:curveProperty>

<gml:LineString srsName="EPSG:4283">

<gml:posList>-27.7358319997469 152.702232000207 0 -27.7415591793126 152.701186819816 0</gml:posList>

</gml:LineString>

</fme:curveProperty>

</fme:Roads>

</fme:featureMember>

Because the geography::GeomFromGml Static Method does not like namespace prefixes, and cannot handle 3D ordinate values (the source data is 2D), I need to remove them from each GML snippet as in the following example:

select geography::GeomFromGml('<LineString xmlns="http://www.opengis.net/gml"><posList>-27.7358319997469 152.702232000207 -27.7415591793126 152.701186819816</posList></LineString>',4283);

Can anyone suggest how I can do this in FME? Different Writer? More XML processing?

regards

Simon Greener

Hi @simongreener, I dont have much experience with this specific GML writer, but I do know that the generic GML writer has more settings for the GML version that might result in what you are looking for.

Another option of the generic GML writer is to use the application schema as GML version.

Hope this helps.


Hi @simongreener, if you just need to create XML snippets for each line geometry with a specific format, simple string concatenation could be easier than GML/XML manipulations. e.g.

  1. CoordinateSwapper (Swap Type: X <-> Y)
  2. CoordinateConcatenator (Coordinate Delimiter: <space>; Coordinate Element Delimiter <space>; Coordinate Element(s) To Include: X, Y; Coordinate Attribute: _coordinates)
  3. StringConcatenator:
<LineString xmlns="http://www.opengis.net/gml"><posList>@Value(_coordinates)</posList></LineString>

Another option is to use the SF GML wirter and correct the poslist by removing the Z coordinate and rewriting the GML via a Text writer.


Thanks to itay and takashi for the suggestions.

I have taken a look at other gml datasets available on the web and most have namespace prefixes so the problem is not something that can be solved just in FME.

I have come up with a solution that sees the gml document being ingested into a single row/column of a SQL Server table, and then manipulated by a combination of SQL Server XML and string processing (sadly, I agree that string manipulation of the XML is easier than trying to process with XML manipulations only).

Here is an example of the processing to extract single linestrings (another insert / select is needed for the multiLineStrings)

Thanks to all.

Simon

INSERT INTO eRoad (ObjectId,Street, RoadType,Shape_Length,line)
SELECT f.objectid,f.street,f.roadtype,Shape_Length,
       geography::GeomFromGml ( f.linestring, 4283 ) as line
  FROM (SELECT road.child.value('declare namespace fme="http://www.safe.com/gml/fme"; 
                                 fme:OBJECTIDg1]','int') as objectId,
               road.child.value('declare namespace fme="http://www.safe.com/gml/fme"; 
                                 fme:STREET'1]',  'varchar(100)') as Street,
               road.child.value('declare namespace fme="http://www.safe.com/gml/fme"; 
                                 fme:ROADTYPE<1]','int') as RoadType,
               road.child.value('declare namespace fme="http://www.safe.com/gml/fme"; 
                                 fme:Shape_Length 1]','float') as Shape_Length,
               replace(replace(replace(replace(replace(
                 CAST(road.child.query('declare namespace fme="http://www.safe.com/gml/fme"; 
                                        fme:curveProperty/*')  as varchar(max)),
                 'p1:',''),' 0 ',' '),' 0<','<'),':p1',''),'srsName="EPSG:4283"','')
                 as linestring
          FROM RoadGML a
               CROSS APPLY
               a.gml.nodes('declare namespace fme="http://www.safe.com/gml/fme"; 
                            /fme:FeatureCollection/fme:featureMember/fme:Roads') AS Road(child)
         WHERE a.gml.exist('declare namespace fme="http://www.safe.com/gml/fme";
                            declare namespace gml="http://www.opengis.net/gml";
                            /fme:FeatureCollection/fme:featureMember/fme:Roads/fme:curveProperty')=1
      ) as f
 WHERE len(f.linestring)<>0;

Reply