3

I have made a WFS connection and got a layer from it. I want to use the first feature from that layer.

driver = ogr.GetDriverByName("WFS")
wfs_url = "WFS:http://example.com/wfs"
wfs = driver.Open(wfs_url)
layer = wfs.GetLayerByName("mylayer")

Now I want to use the first feature from it.

>>> print(sessionlayer[0])
None
>>> type(sessionlayer[0])
<class 'NoneType'>

Why does layer[0] not give me the first feature? What is that layer[0] element?

If I loop over the features of the layer, I do not get that weird None element:

for i, feature in enumerate(sessionlayer):
  print(i, feature)

gives me

0 <osgeo.ogr.Feature; proxy of <Swig Object of type 'OGRFeatureShadow *' at 0x7f33cca12690> >
1 <osgeo.ogr.Feature; proxy of <Swig Object of type 'OGRFeatureShadow *' at 0x7f33cca126c0> >
...
...

Shouldn't the first printed element be that None again?

  • That sounds reasonable. However if I access features via indexes I get some. sessionlayer[1] to [4] correspond to features with gml_ids 1 to 4. Higher elements again return None. The other features have gml_ids in the 1000s so the index do not correspond. I am fine with using next() but I would love to find out what really happens. – bugmenot123 Mar 28 '16 at 14:56
4

You weren't requesting the first feature, you were requesting a feature with an FID of "0" and your WFS doesn't have a feature with an FID of "0".

Why: The ogr.Layer.__getitem__ method which allows element and slice access, calls the ogr.Layer.GetFeature method. GetFeature fetches a feature by its identifier, not by its position. This is intentional, so probably not a bug, but is quite unpythonic...

Note: Iterating over features is supposed to read them sequentially but does not seem to...

Example:

from osgeo import ogr
ogr.UseExceptions() #I thought this **should** cause ogr to raise an exception when asking for a non-existent feature, but it doesn't...

#This is a public WFS
url = 'http://www.environment.gov.au/mapping/services/ogc_services/World_Heritage_Areas/MapServer/WFSServer'

driver = ogr.GetDriverByName("WFS")
wfs_url = "WFS:"+url
wfs = driver.Open(wfs_url)
layer = wfs.GetLayerByIndex(0)

feat0 = layer[0]
print(feat0 is None)
# prints True

feat38 = layer[38]
print(feat38.GetFID())
# prints 38

for f in layer:
    print(f.GetFID())

# prints a very strange order...
# 38
# 39
# 40
# 1
# 2
# 3
# <snip 4-28>
# 29
# 30
# 31
# 41
# 42
# 43
# 44
# 45
# 46
# 32
# 33
# 34
# 35
# 36
# 37

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.