Search code examples
pythonshapefilefiona

How to get output from Fiona instead of fiona.model object


I'm following the examples in the docs but using Virginia's parcel shp file. Warning: it's about 1GB zipped and 1.8GB unzipped.

I have very simply

fiava = fiona.open("VirginiaParcel.shp/VirginiaParcel.shp", layer='VirginiaParcel')

from which I can do fiava.schema to get

# {'properties': {'FIPS': 'str:8',
#   'LOCALITY': 'str:64',
#   'PARCELID': 'str:64',
#   'PTM_ID': 'str:64',
#   'LASTUPDATE': 'date',
#   'VGIN_QPID': 'str:50'},
#  'geometry': 'Polygon'}

So far so good

but when I do

fiava[0]
## I get a Feature object, not the data
## <fiona.model.Feature at 0x7f2fd582aa10>

In the docs it shows this output

{'geometry': {'coordinates': [[(-4.663611, 51.158333),
                            (-4.669168, 51.159439),
                            (-4.673334, 51.161385),
                            (-4.674445, 51.165276),
                            (-4.67139, 51.185272),
                            (-4.669445, 51.193054),
                            (-4.665556, 51.195),
                            (-4.65889, 51.195),
                            (-4.656389, 51.192215),
                            (-4.646389, 51.164444),
                            (-4.646945, 51.160828),
                            (-4.651668, 51.159439),
                            (-4.663611, 51.158333)]],
            'type': 'Polygon'},
'id': '1',
'properties': OrderedDict([('CAT', 232.0), ('FIPS_CNTRY', 'UK'), ('CNTRY_NAME', 'United Kingdom'), ('AREA', 244820.0), ('POP_CNTRY', 60270708.0)]),
'type': 'Feature'}

If I use the schema for the specific keys then I can get data one value at a time but this is not optimal

fiava[0]['properties']['FIPS']
## 51149

Even if I do fiava[0].items() then it's just an ItemsView

What am I missing?


Solution

  • You can use fiona.model.to_dict()

    from fiona.model import to_dict
    d = to_dict(fiava[0])
    

    if you want to serialize the data as json without calling to_dict() on each object, you can use the fiona.model.ObjectEncoder:

    import json
    from fiona.model import ObjectEncoder
    
    j = json.dumps(fiava, cls=ObjectEncoder)