Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

layer kwarg behavior in 1.9 vs 1.10 #1455

Closed
perrygeo opened this issue Sep 27, 2024 · 4 comments
Closed

layer kwarg behavior in 1.9 vs 1.10 #1455

perrygeo opened this issue Sep 27, 2024 · 4 comments

Comments

@perrygeo
Copy link
Collaborator

perrygeo commented Sep 27, 2024

Expected behavior and actual behavior.

In fiona 1.9.6, the following code was valid

feat = '{"type": "Feature", "properties": {}, "geometry": null}'
with fiona.open(feat, "r", layer=0) as f:
    assert len(f) == 1

but fails with fiona 1.10.1 with something like

Traceback (most recent call last):
  File "/home/mperry/projects/python-rasterstats/try.py", line 5, in <module>
    with fiona.open(a, "r", layer=0) as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mperry/.virtualenvs/rasterstats/lib/python3.12/site-packages/fiona/env.py", line 457, in wrapper
    return f(*args, **kwds)
           ^^^^^^^^^^^^^^^^
  File "/home/mperry/.virtualenvs/rasterstats/lib/python3.12/site-packages/fiona/__init__.py", line 342, in open
    colxn = Collection(
            ^^^^^^^^^^^
  File "/home/mperry/.virtualenvs/rasterstats/lib/python3.12/site-packages/fiona/collection.py", line 226, in __init__
    self.session.start(self, **kwargs)
  File "fiona/ogrext.pyx", line 887, in fiona.ogrext.Session.start
ValueError: Null layer: <closed Collection '{"type": "Feature", "properties": {}, "geometry": null}:{"type": "Feature", "properties": {}, "geometry": null}', mode 'r' at 0x7f2c9e9488f0> {"type": "Feature", "properties": {}, "geometry": null}

I didn't see anything obvious in the CHANGES. Is there a move away from the OGR convention of layer 0 as the default?

Note that opening GeoJSON strings work fine if you omit the layer kwarg.

Steps to reproduce the problem.

see above

Operating system

Linux x86_64

Fiona and GDAL version and provenance

Fiona 1.10.1 binary wheel from pypi

@sgillies
Copy link
Member

@perrygeo the layer=0 usage is intended to be valid. In fact, under the hood we do self.layer = layer or 0 (https://github.com/Toblerity/Fiona/blob/main/fiona/collection.py#L176). I think the problem is more likely to be with the input. I'm not sure that the GeoJSON driver ever intended to open a single feature, and this might have changed in a recent version.

@perrygeo
Copy link
Collaborator Author

I get the same behavior with a FeatureCollection:

feat = '{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": null}]}'

with fiona.open(feat, "r", layer=0) as f:
    assert len(f) == 1

which runs in 1.9.6 but gives this traceback in 1.10.1

Traceback (most recent call last):
  File "/home/mperry/projects/python-rasterstats/try.py", line 11, in <module>
    with fiona.open(feat, "r", layer=0) as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mperry/.virtualenvs/rasterstats/lib/python3.12/site-packages/fiona/env.py", line 457, in wrapper
    return f(*args, **kwds)
           ^^^^^^^^^^^^^^^^
  File "/home/mperry/.virtualenvs/rasterstats/lib/python3.12/site-packages/fiona/__init__.py", line 342, in open
    colxn = Collection(
            ^^^^^^^^^^^
  File "/home/mperry/.virtualenvs/rasterstats/lib/python3.12/site-packages/fiona/collection.py", line 226, in __init__
    self.session.start(self, **kwargs)
  File "fiona/ogrext.pyx", line 887, in fiona.ogrext.Session.start
ValueError: Null layer: <closed Collection '{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": null}]}:{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": null}]}', mode 'r' at 0x7efd34a036b0> {"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": null}]}

The workaround is to json.load the string and handle as a python dict instead of invoking ogr. This is not ideal though as it leads to two code paths; one for GeoJSON payloads, one for OGR datasets. It's fine for my use case (rasterstats) since I've already written and tested that code path. So no urgency on my part.

@sgillies
Copy link
Member

Given a well-formed GeoJSON file, layer=0 is as good as it ever was in version 1.10.1.

>>> with fiona.open("/Users/seangillies/projects/Fiona/tests/data/coutwildrnp.json", layer=0) as collection:
...     features = list(collection)
...
>>> len(features)
67

The code at https://github.com/Toblerity/Fiona/blob/main/fiona/ogrext.pyx#L880-L887 isn't substantially different from the code in 1.9.6, so I suspect that the most recent version of GDAL returns NULL when it doesn't find any useful feature in the GeoJSON file.

@perrygeo
Copy link
Collaborator Author

perrygeo commented Sep 29, 2024

In my case the string is GeoJSON, not a file path. Arguably opening a geojson string as a data source isn't even a good idea, but it used to work so it became part of rasterstats public API. Hyrum's law strikes again!

It could very well be GDAL changes. Looks like the Fiona 1.9.6 wheel was built with GDAL 3.6.4, and the 1.10.1 wheel was built with GDAL 3.9.2. So the change happened somewhere in there.

In any case, it doesn't seem like a fiona issue so I'll close here. We have two workarounds - load it into python dicts, or build against an older GDAL.

Thanks @sgillies !

@perrygeo perrygeo closed this as not planned Won't fix, can't repro, duplicate, stale Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants