Fiona: Properties seems to be required

Created on 10 Dec 2019  路  3Comments  路  Source: Toblerity/Fiona

Expected behavior and actual behavior.

The geo interface documentation says that properties is optional, yet it appears to be required by Fiona.

Steps to reproduce the problem.

If I define a schema like so...

schema = {
    "geometry": "Polygon",
    # No properties defined here.
}

This already gives an error if I try to use this schema:

import fiona
from fiona.crs import from_epsg

f = fiona.open("tmp.shp", "w", schema={"geometry": "Polygon"}, crs=from_epsg(3035), driver="GeoJSON")                     
~/Workspace/anaconda/envs/et/lib/python3.7/site-packages/fiona/env.py in wrapper(*args, **kwargs)
    404             with Env.from_defaults(session=session):
    405                 log.debug("Credentialized: {!r}".format(getenv()))
--> 406                 return f(*args, **kwargs)
    407     return wrapper
    408 

~/Workspace/anaconda/envs/et/lib/python3.7/site-packages/fiona/__init__.py in open(fp, mode, driver, schema, crs, encoding, layer, vfs, enabled_drivers, crs_wkt, **kwargs)
    256                 # Make an ordered dict of schema properties.
    257                 this_schema = schema.copy()
--> 258                 this_schema['properties'] = OrderedDict(schema['properties'])
    259             else:
    260                 this_schema = None

KeyError: 'properties'

If I amend the schema to have an empty properties field:

schema = {
    "geometry": "Polygon",
    "properties": {},
}

then the f = fiona.open("tmp.shp", "w", schema={"geometry": "Polygon"}, crs=fiona.crs.from_epsg(3035), driver="GeoJSON") call works, but I still get an error when trying to add a shape without a properties key. The following code...

import fiona
from fiona.crs import from_epsg
from shapely.geometry import Polygon, mapping

with fiona.open(
            "tmp.shp",
            "w",
            driver="GeoJSON",
            crs=from_epsg(3035),
            schema=schema) as source:
    polygon = Polygon(
        [
            (0, 0),
            (1, 0),
            (1, 1),
            (1, 0)
        ]
    )

    shape = dict(geometry=mapping(invalid_shape))
    source.write(shape)

gives the error

~/Workspace/anaconda/envs/et/lib/python3.7/site-packages/fiona/collection.py in write(self, record)
    351     def write(self, record):
    352         """Stages a record for writing to disk."""
--> 353         self.writerecords([record])
    354 
    355     def validate_record(self, record):

~/Workspace/anaconda/envs/et/lib/python3.7/site-packages/fiona/collection.py in writerecords(self, records)
    345         if self.mode not in ('a', 'w'):
    346             raise IOError("collection not open for writing")
--> 347         self.session.writerecs(records, self)
    348         self._len = self.session.get_length()
    349         self._bounds = self.session.get_extent()

fiona/ogrext.pyx in fiona.ogrext.WritingSession.writerecs()

KeyError: 'properties'

It seems that the properties key is required both in the schema and in the written data, even though the spec doesn't seem to require it. Merely using empty dicts appears to fix this issue, but Fiona probably shouldn't require these keys at all.

Operating system

Ubuntu 18.04.

Fiona and GDAL version and provenance

Fiona 1.8.6 via pip on Python 3.7.3 via conda.

bug resolved

All 3 comments

Thanks @SeanDS . Features and datasets without non-geometry properties haven't been on our radar. I'm not sure if all formats allow them, but the library probably doesn't need to require them.

How should unexpected keys be handled? For example:

feature = {
    "geometry": {"type": "Point", "coordinates": [0, 0]},
    "property": {"name": "example"},  # a mistake, should be properties
}
collection.write(feature)

In the current behaviour an exception would be raised. I guess this should still raise if the feature doesn't match the properties in the schema?

@snorfalorpagus good question. The GeoJSON driver can handle extra keys in a limited way (see "NATIVE_DATA" under https://gdal.org/drivers/vector/geojson.html#open-options), but no other driver can. In fiona 2 your code won't be valid, we'll have a real Feature class with a proper constructor with specific keyword arguments. Meanwhile, for 1.8 and 1.9 let's be pragmatic: don't require properties in the schema, but do require that features match the schema. How about that?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

culebron picture culebron  路  4Comments

klonuo picture klonuo  路  3Comments

dazza-codes picture dazza-codes  路  3Comments

sgillies picture sgillies  路  4Comments

sgillies picture sgillies  路  4Comments