1

I use OpenLayers 4.6 and I want to read a feature from GML string. The GML looks like:

<?xml version="1.0" encoding="UTF-8"?>
<gml:Polygon xmlns:gml="http://www.opengis.net/gml" 
    xmlns:sch="http://www.ascc.net/xml/schematron" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" srsDimension="2">
   <gml:exterior>
      <gml:LinearRing srsDimension="2">
         <gml:posList>37.15 36.15 37.15 36.3 37.5 36.3 37.5 36.15 37.15 36.15</gml:posList>
      </gml:LinearRing>
   </gml:exterior>
</gml:Polygon>

I know that I need to specify the featureNS and featureType to read the feature using ol.format.GML3, but I don't know how to set them properly:

let feature = new ol.format.GML3({
  srsName: 'EPSG:4326',
  featureType: '???',
  featureNS: '???'
}).readFeatures(data);

3 Answers 3

2
+50

I stored your gml data as .gml file and tried to open it using QGIS(Add Vector Layer). I got an error saying "invalid data source". As far as I know valid gml should have features inside featureCollection(please correct me if I'm wrong). Then I tried to get features of another gml source(took sample data from http://worldmap.harvard.edu/data/geonode:mypolygon_px6). OL parsed sample data. I tried to parse your data with same options, but unfortunately I got and empty array. To check please have a look at: https://jsfiddle.net/d08s532r/27/ May be your data is not valid gml source for OL.

0
1

These parameters allow you to limit what you extract from the GML. It's a bit odd to have it in the format descriptor, as this originates from the way WFS requests are done (you'll find the same namespace and type there).

In your example, your GML already is very flat, without any a "superstructure" (all features are equal, next to each other), so you should just leave both of these empty (read everything from the file as-is).

If you have issues with this, I seem to remember that OL changed some things around, so since OL 3.x you can just use a ol.format.WFS() (without any extra options necessary. You can still use projection if you want.) to parse simple GML data.

Additional explanation:

WFS offer their features with unique names in this style: app:river.

featureType is the feature you want from the WFS service. this is what you get in your getCapabilities request (as a WFS can offer multiple featuretypes at once). So you would set river here.

The featureNS is an additional WFS parameter, which has to be specified if your features are from a specific namespace. This is simply the prefix of each feature your WFS provides (the string before the :). In this case, app. Your WFS could also offer different namespaces, e.g. a app2:river, in which case this would be relevant. These are the unusual cases the OL docs try to explain (what to do when you want to request multiple featuretypes from multiple namespaces in a single WFS request).

If you have complicated data, the GML can have the features with this "superstructure" intact, sorting them into namespaces and featuretypes. In that case, you can add these values to your GML format object to filter the data.

7
  • Thanks Senshi for the valuable information (for me as a beginner), so as I understand for my example I don't need to specify the featureNS and featureType, but when I execute the code above it returns a null result, so what is the problem?
    – abd0991
    Commented Apr 9, 2018 at 11:01
  • did you try with ol.format.WMS()?
    – Senshi
    Commented Apr 9, 2018 at 11:38
  • No, but WMS or WFS? I will give it a try.
    – abd0991
    Commented Apr 9, 2018 at 11:46
  • I tried o.format.WFS and also the same result 'null'
    – abd0991
    Commented Apr 9, 2018 at 12:07
  • let feature = new ol.format.WFS().readFeatures(data, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:4326' });
    – abd0991
    Commented Apr 9, 2018 at 12:08
0

I came across a similar thing today when trying to load a single geometry (note: I'm using OpenLayers 3.something, but I suspect that not a lot has changed). The ol.format.GML3 type doesn't have a single reader, so I had to use readFeatures, which is designed to load multiple geometries.

The readFeatures method expects there to be a FeatureCollection (looking at the source, it uses .localName to identify it, so it doesn't matter what namespace it's in), then looks for featureMembers within it (again, using .localName, so namespaces are irrelevant). Within that it's expecting to find another element, which represents your feature (and it's this that the featureNS and featureType identify), then a geometry element (it skips boundedBy). I ended up wrapping my GML string like so:

let feature = new ol.format.GML3({
  srsName: 'EPSG:4326',
  featureType: 'dummy',
  featureNS: 'http://abcdef.xyz/dummy'
}).readFeatures(
  '<x:FeatureCollection xmlns:x="http://www.opengis.net/gml" xmlns:y="http://abcdef.xyz/dummy">' + 
  '  <x:featureMember>' + 
  '    <y:dummy>' + 
  data + 
  '    </y:dummy>' + 
  '  </x:featureMember>' + 
  '</x:FeatureCollection>'
);

This works, but could be better I suspect. I also suspect that since GML3.2.* deprecates the feature collection, namespace x could be anything as well (plus, inspection of the code backs this up). Note: The variable called 'feature' will actually be an array of ol.Feature

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.